J'ai une fonction où je crée dynamiquement plusieurs formules en tant que chaînes et les transpose en formules avec as.formula
. J'appelle alors cette fonction dans un processus parallèle en utilisant doSNOW
et foreach
et utilise ces formules par dplyr::mutate_
.Comment fonctionne chaque environnement de classe R pour chaque package lors de l'utilisation de as.formula, SE dplyr et lapply?
Lorsque j'utilise lapply(formula_list, as.formula)
, j'obtiens l'erreur could not find function *custom_function*
lorsqu'elle est exécutée en parallèle, bien qu'elle fonctionne correctement lorsqu'elle est exécutée localement. Cependant, quand j'utilise lapply(formula_list, function(x) as.formula(x)
cela fonctionne à la fois en parallèle et localement.
Pourquoi? Quelle est la bonne façon de comprendre les environnements ici et la «bonne» façon de le coder?
je reçois un avertissement qui dit: In e$fun(obj, substitute(ex), parent.frame(), e$data) : already exporting variable(s): *custom_func*
Un exemple reproductible minimale est inférieure.
# Packages
library(dplyr)
library(doParallel)
library(doSNOW)
library(foreach)
# A simple custom function
custom_sum <- function(x){
sum(x)
}
# Functions that call create formulas and use them with nse dplyr:
dplyr_mut_lapply_reg <- function(df){
my_dots <- setNames(
object = lapply(list("~custom_sum(Sepal.Length)"), as.formula),
nm = c("Sums")
)
return(
df %>%
group_by(Species) %>%
mutate_(.dots = my_dots)
)
}
dplyr_mut_lapply_lambda <- function(df){
my_dots <- setNames(
object = lapply(list("~custom_sum(Sepal.Length)"), function(x) as.formula(x)),
nm = c("Sums")
)
return(
df %>%
group_by(Species) %>%
mutate_(.dots = my_dots)
)
}
#1. CALLING BOTH LOCALLY
dplyr_mut_lapply_lambda(iris) #works
dplyr_mut_lapply_reg(iris) #works
#2. CALLING IN PARALLEL
#Faux Parallel Setup
cl <- makeCluster(1, outfile="")
registerDoSNOW(cl)
# Call Lambda Version WORKS
foreach(j = 1,
.packages = c("dplyr", "tidyr"),
.export = lsf.str()
) %dopar% {
dplyr_mut_lapply_lambda(iris)
}
# Call Regular Version FAILS
foreach(j = 1,
.packages = c("dplyr", "tidyr"),
.export = lsf.str()
) %dopar% {
dplyr_mut_lapply_reg(iris)
}
# Close Cluster
stopCluster(cl)
EDIT: Dans le titre de mon message original j'ai écrit que j'utilisais NSE, mais je voulais vraiment dire utiliser l'évaluation standard. Oups. J'ai changé cela en conséquence.
Cela semble super utile! Je vais certainement étudier la question plus en détail, mais je vais laisser la question ouverte afin que je puisse mieux comprendre le problème fondamental. – bigfoot56