foreach 中的导出变量

Posted

技术标签:

【中文标题】foreach 中的导出变量【英文标题】:Export variable in foreach 【发布时间】:2016-01-06 11:09:47 【问题描述】:

我在将数据框导出到 foreach 包中的 %dopar% 时遇到问题。如果我将%do%registerDoSEQ() 一起使用,它会起作用,但与registerDoParallel() 我总是得到:

Error in  : task 1 failed - "object 'kyphosis' not found"

这是一个使用来自rpart 包的kyphosis 数据的可重现示例。我正在尝试并行化逐步回归:

library(doParallel)
library(foreach)
library(rpart)

invars <- c('Age', 'Number', 'Start')
n_vars <- 2
vars <- length(invars)
iter <- trunc(vars/n_vars)
threads <- 4
if (vars%%n_vars == 0) iter <- iter - 1
iter <- 0:iter

cl <- makeCluster(threads)
registerDoParallel(cl)
#registerDoSEQ()

terms <- ''
min_formula <- paste0('Kyphosis~ 1', terms)
fit <- glm(formula = as.formula(min_formula), data = kyphosis, family = 'binomial')

out <- foreach(x = iter, .export = 'kyphosis') %dopar%  

  nv <- invars[(x * n_vars + 1):(min(x * n_vars + n_vars, vars))]
  sfit <- step(object = fit, trace =FALSE, scope = list(
    lower = min_formula,
    upper = as.formula(paste(min_formula, '+', paste0(nv, collapse = '+')))),
    steps = 1, direction = 'forward')
  aic <- sfit$aic

  names(aic) <- if(nrow(sfit$anova) == 2) sfit$anova$Step[2]
  aic

out
stopCluster(cl)

【问题讨论】:

(iter为用户自定义变量) 我不知道为什么它不起作用,但是您可以通过将 glm 调用放在循环中来使其起作用。我希望它有助于故障排除。我怀疑问题在于 step 函数如何使用 fit 对象中的数据。 @antoine-sac 是的,它是这样工作的,但我尽量避免这样做,因为没有必要让每个工人都适应模型。 由于 kyphosis 数据框是在 rpart 包中定义的,您可以尝试使用 foreach .packages="rpart" 选项。这通常比尝试导出对象效果更好。 【参考方案1】:

在调用step函数之前在foreach的正文中添加这个:

.GlobalEnv$kyphosis <- kyphosis

我不确定为什么会发生这种情况,但我的直觉是step 使用存储在fit$call 中的信息在其内部调用glm,即

glm(formula = as.formula(min_formula), family = "binomial", data = kyphosis)

使用新的更新公式,但data = kyphosis 部分保持不变。所以glm 尝试在全局环境中寻找kyphosis

【讨论】:

以上是关于foreach 中的导出变量的主要内容,如果未能解决你的问题,请参考以下文章

在foreach循环中调用导出

如何在“R”中的foreach循环中导出多个函数或包

通过数组中的C#中的成员变量迭代(foreach)[重复]

自动完成 foreach 中的变量

C# - 将'foreach'中的变量传递给其他文件

Foreach和doparallel而不是R中的for循环