Foreach с% dopar% не может обнаружить пользовательскую функцию внутри пользовательской функции - PullRequest
1 голос
/ 03 июля 2019

Я выполняю цикл foreach с% dopar% в R. Я создал две пользовательские функции. Я вызываю одну пользовательскую функцию, скажем X внутри другой пользовательской функции, скажем Y. foreach не может обнаружить функцию X, если я создаю список, L содержит функцию Y и вызывает функцию Y из L.

Я пытался использовать .export. Моя функция может работать плавно, если я не использую список функций с функцией Y, содержащей функцию X.

Минимальный рабочий код выглядит следующим образом:

# Define the function
Fun1=function(x){
  a=2*x
  b=3*x
  c=a+b
  return(c)
}
Fun2=function(x){
  a=x
  b=Fun1(x)
  c=a+b
  return(c)
}

# Create a list containing function Fun1 and Fun2
Funlist=list(Fun1, Fun2)

# Create a variable
x=1

# Run Normal Loop
for(i in 1:10){
  a=Funlist[[1]](x)
}
### Output: a=6

# Run the foreach loop
library("foreach")
library("parallel")
library("doParallel")
library("DoE.base")

registerDoParallel(7)

## Scenario 1: Run foreach loop with Fun2
df_c=foreach(seed = 1:10, .combine=rbind)%dopar%{a=Fun2(x)}
### Output: No error

## Scenario 2: Run foreach loop with Fun1 from Funlist
df_c=foreach(seed = 1:10, .combine=rbind)%dopar%{a=Funlist[[1]](x)}
### Output: No error

## Scenario 3: Run foreach loop with Fun2 from Funlist
df_c=foreach(seed = 1:10, .combine=rbind)%dopar%{a=Funlist[[2]](x)}
### Output: Error in { : task 1 failed - "could not find function "Fun1""

Я ожидаю, что вывод не будет ошибкой, поскольку df_c предоставит мне фрейм данных.

1 Ответ

0 голосов
/ 04 июля 2019

Reprex

# Define the functions
Fun1 <- function(x) 2 * x
Fun2 <- function(x) Fun1(x + 1)

# Create a list containing functions Fun1 and Fun2
Funlist <- list(Fun1, Fun2)

# Run the foreach loop
library(doParallel)
registerDoParallel(cl <- makeCluster(2))

## Scenario 1: Run foreach loop with Fun2 
## Output: No error
foreach(x = 1:10) %dopar% Fun2(x)

## Scenario 2: Run foreach loop with Fun1 from Funlist 
## Output: No error
foreach(x = 1:10) %dopar% Funlist[[1]](x)

## Scenario 3: Run foreach loop with Fun2 from Funlist
## Output: Error in { : task 1 failed - "could not find function "Fun1""
foreach(x = 1:10) %dopar% Funlist[[2]](x)

Решение

Мое предпочтительное решение: никогда не полагаться на глобальные объекты и всегда передавать объекты в качестве аргументов функций.

Fun3 <- function(x, Fun) Fun(x + 1)
Funlist2 <- list(Fun1, Fun3)
foreach(x = 1:10) %dopar% Funlist2[[2]](x, Funlist2[[1]])

stopCluster(cl)
...