【问题标题】:Functions not finding variables, or environment, when inside a foreach loop在 foreach 循环中找不到变量或环境的函数
【发布时间】:2018-02-28 03:30:14
【问题描述】:

我正在尝试构建一个R package,它在几个nested foreach 循环中包含一个顶级函数。然后这个顶级函数调用一组进一步的嵌套函数。我遇到的问题是词法范围,较低级别的函数找不到我放置变量的环境或变量。我已经尝试使用attach,根据这个例子attach,但较低的函数仍然看不到必要的参数。我知道使用分叉方法的 doMPI 有一些特定的内容。这是在 Ubuntu Linux (16.04) 上,使用 doMPI (0.2.2) 和 foreach (1.4.3) 和 openmpi。这是我拥有的更大模型的mwe。该软件包和一个名为toymod4 package 的运行/测试脚本可供下载。

#' Test function level 1
#' @param num.sim first variable for function 1
#' @param num.per second variable for function 1
#' @param num.day third variable for function 1
#' @param fun2.params parameters for function 2
#' @param fun31.params parameters for first call of function 3
#' @param fun32.params parameters for second call of funtion 3
#' @param fun4.params parameters for call to function 4
#' @export fun1
fun1 <- function (fun2.params, fun31.params, fun32.params, fun4.params,
                  num.sim=10, num.per=8, num.day=5, ...) {
    final.results <- data.frame (foreach::`%dopar%`(
        foreach::`%:%`(foreach::foreach(j = 1:num.sim,
                                        .combine = cbind,
                                        .packages= c("toymod4")),
                       foreach::foreach (i = 1:num.per,
                                         .packages = c("toymod4"),
                                         .combine=rbind)), {
            e1 <- new.env()
            e1 <- list2env(c(fun2.params, fun31.params, fun32.params,
                             fun4.params), e1)
            out3 <- replicate(num.day, fun2(e1, var21, var22, fun22on))
            out2 <- data.frame(mean(out3))
        }
    )
    )
    ## save outputs for subsequent analyses if required
    saveRDS(final.results, file = paste(num.day ,"_", num.per, "_", num.sim, "_",
                                        format(Sys.time(), "%d_%m_%Y"),
                                        ".rds", sep=""))
    return(final.results)
}

#' Test function level 2
#' @param var21 first variable for function 2
#' @param var22 second variable for function 2
#' @param fun22on turn this copy of fun3 on or off
#' @param env environment to get variables from 
#' @export fun2
fun2 <- function (env, var21, var22, fun22on, ...) {
    attach(env)
    out21 <- ifelse (rpois(1, var21) > 0, var22 * fun3(e1, fun3on, var31), 0)
    out22 <- ifelse (fun22on, fun3(e1, fun3on, var31), 0)
    out2 <- out21 + out22
    detach(env)
    out2
}

#' Test function level 3
#' @param var31 first variable for function 3
#' @param fun3on turn the formula on or off
#' @export fun3
fun3 <- function (env, fun3on, var31, ...) {
    attach(env)
    out31 <- ifelse (fun3on, var31, 1)
    out32 <- ifelse (fun3on, fun4(e1, fun4on, var41), 0)
    out3 <- out31 + out32
    detach(env)
    out3
}

#' Test function level 4
#' @param var41 first variable for function 4
#' @param fun4on turn the formula on or off
#' @export fun4
fun4 <- function (env, fun4on, var41, ...) {
    attach(env)
    out4 <- ifelse (fun4on, var41, 1)
    detach(env)
    out4
}

【问题讨论】:

  • 你试过什么电话?有哪些论据?请注意,我想我们已经回答了类似的问题。
  • 它们相似但不相同,所以我认为它没有得到回答。我仍然试图避免通过每个函数传递每个参数。对于实际模型,这意味着将 80 个参数传递给第一个函数,然后将其中的 75 个传递给第二个函数……以此类推。如果我能找到一种方法来限制它工作的环境,那么它会“看到”它们,对吗?而且 doMPI 不像 doParallel 那样顺从。该调用也很复杂,添加到此注释的工具很大,但它位于 github 上的驱动程序文件中。对不起。

标签: r foreach parallel-processing dompi


【解决方案1】:

在 Steve Weston 的慷慨帮助下,我设法解决了这个问题。与其试图解释这一切,我已经将它发布在 github 上的这个地址 https://github.com/jamaas/VarPasMpiExamp.git 这是将变量值传递给包含在 foreach 循环中的函数的一种方法。从理论上讲,它应该适用于 R,任何操作系统上的 foreach,使用任何并行后端,但尚未在所有操作系统上进行测试。该版本的开发和测试是在 Ubuntu 16.04 (Debian) Linux 上完成的。让我知道这种方法是否适合您,或者特别是如果您有更简单、更优雅的解决方案。

【讨论】:

    猜你喜欢
    • 2011-06-13
    • 1970-01-01
    • 2018-01-27
    • 2018-12-27
    • 2016-07-11
    • 2013-04-17
    • 2015-11-08
    • 1970-01-01
    相关资源
    最近更新 更多