当使用 as.formula、SE dplyr 和 lapply 时,每个包如何限定 R 环境的范围



我有一个函数,我可以在其中动态构建多个公式作为字符串,并将它们转换为具有as.formula的公式。然后,我使用 doSNOWforeach 在并行过程中调用该函数,并通过 dplyr::mutate_ 使用这些公式。

当我使用lapply(formula_list, as.formula)并行运行时,我could not find function *custom_function*出现错误,尽管在本地运行时它工作正常。但是,当我使用lapply(formula_list, function(x) as.formula(x)时,它可以并行和本地工作。

为什么?理解这里的环境的正确方法以及编码的"正确"方法是什么?

我确实收到一条警告,上面写着:In e$fun(obj, substitute(ex), parent.frame(), e$data) : already exporting variable(s): *custom_func*

下面是一个最小的可重现示例。

# 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)   

编辑:在我最初的帖子标题中,我写道我正在使用nse,但我真的是使用标准评估。哎 呦。我已经相应地更改了此设置。

我在这里没有

确切的答案,但是未来的包(我是作者(处理这些类型的"棘手"全局变量 - 它们很棘手,因为它们不是包的一部分并且它们是嵌套的,即一个全局调用另一个全局。 例如,如果您使用:

library("doFuture")
cl <- parallel::makeCluster(1, outfile = "")
plan(cluster, workers = cl)
registerDoFuture()

那个有问题的"调用常规版本失败"的情况现在应该可以工作了。

现在,上面使用默认为 type = "PSOCK"parallel::makeCluster(),而如果您加载 doSNOW,则会得到默认为 type = "MPI"snow::makeCluster()。 遗憾的是,尚未为未来的软件包实现完整的 MPI 后端。 因此,如果您正在寻找 MPI 解决方案,这(还(对您没有帮助。

相关内容

  • 没有找到相关文章

最新更新