【问题标题】:How does foreach package scope R Environments when using as.formula, SE dplyr, and lapply?使用 as.formula、SE dplyr 和 lapply 时,foreach 包范围 R 环境如何?
【发布时间】:2017-06-21 17:23:36
【问题描述】:

我有一个函数可以动态地将多个公式构建为字符串并将它们转换为带有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,但我的真正意思是使用标准评估。哎呀。我已经相应地改变了这一点。

【问题讨论】:

    标签: r dplyr parallel-foreach snow nse


    【解决方案1】:

    我对这里的原因没有确切的答案,但future 包(我是作者)处理这些类型的“棘手”全局变量 - 它们很棘手,因为它们不是包的一部分,而且它们是嵌套的,即一个全局调用另一个全局。例如,如果您使用:

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

    那个有问题的“调用常规版本失败”案例现在应该可以工作了。

    现在,上面使用parallel::makeCluster(),默认为type = "PSOCK",而如果你加载doSNOW,你会得到snow::makeCluster(),默认为type = "MPI"。不幸的是,一个完整的MPI backend is yet not implemented 用于未来的包。因此,如果您正在寻找 MPI 解决方案,这对您没有帮助(目前)。

    【讨论】:

    • 这看起来超级有用!我当然会对此进行更多调查,但我会保留这个问题,以便我希望更好地理解核心问题。
    猜你喜欢
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    相关资源
    最近更新 更多