Skip to content

Instantly share code, notes, and snippets.

@nanxstats
Last active June 9, 2022 14:22
Show Gist options
  • Save nanxstats/0fa0a09bb10745f3cb4c3ae484eec8c4 to your computer and use it in GitHub Desktop.
Save nanxstats/0fa0a09bb10745f3cb4c3ae484eec8c4 to your computer and use it in GitHub Desktop.
foreach wrapper function that parallelizes any user-supplied expressions
# Get operator (parallel or serial)
# Idea from <https://github.com/tidymodels/tune/blob/c4a1d891ac77e64086a417ab75ad822178cd87ee/R/parallel.R>
get_operator <- function() {
is_par <- foreach::getDoParWorkers() > 1
if (is_par) {
res <- foreach::`%dopar%`
} else {
res <- foreach::`%do%`
}
res
}
#' Parallelize arbitrary user-supplied expression
#'
#' @param expr R expression.
#' @param n Number of iterations.
#' @param seed Initial random seed.
#' @param counter Character string. Name of the loop counter variable. Default is `"i"`.
fpar <- function(expr, n, seed, counter = "i") {
`%op%` <- get_operator()
expr <- substitute(expr)
foreach::foreach(
i = seq_len(n),
# .packages = ...,
# .export = ...,
# .errorhandling = ...,
.combine = "c"
) %op% {
assign(counter, value = i)
set.seed(seed + i - 1)
eval(expr)
}
}
# User code will look like this
library(doParallel)
registerDoParallel(parallel::detectCores())
fpar(
{
x <- exp(log(index))
y <- rnorm(1, sd = 0.1)
x + y
},
n = 10,
seed = 42,
counter = "index"
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment