如何在 R 中将附加参数(存储在“...”中)传递给 parLapply 的多个内核?

How to pass additional parameters (stored in "...") to multiple cores for parLapply, in R?

我正在编写一个函数 f1(),它接受要传递给 f1() 内的函数 f0() 的附加参数“...”。更准确地说,f0() 在 f1 内部的并行 lapply 调用中被调用。只要至少要传递一个参数,它就可以正常工作,但是如果“...”为空,我会收到错误消息:“ Error in get(name, envir = envir) : argument “...”丢失,没有默认值

如果我使用 lapply 而不是 parLapply,它工作正常。

有没有合适的解决办法?我不想在 f1() 的定义中明确定义 f0() 的所有参数。

首先,我用两个可选参数定义函数。

f0 <- function(a, b, d1 = NULL, d2 = NULL){
   if(is.null(d1)){
      ret <- a * b
   }else{
      ret <- a * b / d1
   }
   if(!is.null(d2)){
      ret <- ret - d2
   }
   ret
}

接下来,函数 f1() 和 f1_par() 执行相同的操作,一个使用 sapply,另一个使用 parSapply。

f1 <- function(A, ...){
   # A ... vector of a
   B <- rev(A)

   sapply(seq_along(A), function(i){
      f0(A[i], B[i], ...)
   }) 
}


f1_par <- function(A, ...){
   # A ... vector of a
   B <- rev(A)
   cl <- parallel::makeCluster(2)
   parallel::clusterExport(cl, envir = environment(), c("A", "B", "f0","..."))
   ret <- parallel::parSapply(cl, seq_along(A), function(i){
      f0(A[i], B[i], ...)
   }) 
   parallel::stopCluster(cl)
   ret
}

除了最后一个函数调用之外,我得到了以下所有六个函数调用的正确结果:

A <- 1:4

# sapply
f1(A, d1 = 2, d2 = 4)
f1(A, d1 = 2)
f1(A)

# parSapply
f1_par(A, d1 = 2, d2 = 4)
f1_par(A, d1 = 2)
f1_par(A) # this one causes the error

我很确定你不能那样导出 ...。相反,请确保将 ... 作为参数传递给:

f1 <- function(A, ...) {
   # A ... vector of a
   B <- rev(A)

   sapply(seq_along(A), function(i, ...) {
      f0(A[i], B[i], ...)
   }, ...) 
}

然后,对parallel::parSapply()做同样的事情。