Как передать дополнительные параметры (хранящиеся в «...») нескольким ядрам для parLapply, в R? - PullRequest
0 голосов
/ 31 октября 2019

Я пишу функцию f1 (), которая принимает дополнительные параметры "..." для передачи функции f0 () внутри функции f1 (). Точнее, f0 () вызывается внутри параллельного вызова lapply, внутри f1. Он работает нормально, если есть хотя бы один параметр, который нужно передать, но если "..." пусто, я получаю сообщение об ошибке: "Ошибка в get (name, envir = envir): аргумент" ... "отсутствует, без значения по умолчанию "

Работает нормально, если я использую lapply вместо parLapply.

Есть ли правильное решение? Я не хочу явно определять все параметры для f0 () в определении f1 ().

Во-первых, я определяю функцию с двумя необязательными параметрами.

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

1 Ответ

1 голос
/ 31 октября 2019

Я почти уверен, что вы не можете экспортировать ... таким образом. Вместо этого обязательно передайте ... в качестве аргументов, как в:

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

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

Затем сделайте то же самое с parallel::parSapply().

...