我正在尝试创建一个执行并行引导例程的 R 函数,但在 parLapply 中传递函数参数时遇到困难。 下面是一个(希望)可重现的示例,其中集群无法找到参数的值:
innerFun <- function(a=rnorm(10), q=0.5){
quantile(a, probs = q)
}
library(parallel)
bootFun <- function(a=rnorm(10), q=0.5, nperm=10, no_cores = detectCores() - 1){
parFun <- function(x){
set.seed(x)
ai <- sample(a, size=length(a), replace = TRUE)
return(innerFun(a=ai, q=q))
}
ARGS <- list("innerFun", "a", "q", "nperm")
cl <- parallel::makeCluster(no_cores, type="PSOCK")
nn <- split(1:nperm, 1:nperm)
parallel::clusterExport(cl, varlist = ARGS)
res <- parallel::parLapply(cl, nn, parFun)
parallel::stopCluster(cl)
res <- do.call("rbind", res)
return(res)
}
set.seed(1)
res1 <- bootFun(a=rnorm(100), q=0.5, nperm=10, no_cores = detectCores() - 1)
# Error in get(name, envir = envir) : object 'a' not found
最佳答案
这是parallel::clusterExport 比较棘手的方面之一。正如文档中所说,
clusterExport 将主 R 进程上 varlist 中命名的变量的值分配给每个节点的全局环境(也称为“工作空间”)中的同名变量
也就是说,它在全局环境中查找变量名称。默认的环境参数也演示了这一点
clusterExport(cl = NULL, varlist, envir = .GlobalEnv)
您需要像这样将环境指定为函数(非全局)环境
clusterExport(cl, args, env = environment())
根据您的情况,更新为
parallel::clusterExport(cl, varlist = ARGS, env = environment())
替换为更新版本,这会导致 res1
的输出
50%
1 0.11379733
2 -0.01619026
3 0.05117174
4 -0.11234621
5 0.37001881
6 0.07445315
7 0.01455376
8 -0.03924000
9 0.01481569
10 0.18364332
关于r - 如何使用 parLapply 将参数从外部函数传递到内部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47393416/