这是一个说明我的问题的玩具示例.
library(foreach)
library(doMC)
registerDoMC(cores=2)
foreach(i = 1:2) %dopar%{
i + 2
}
[[1]]
[1] 3
[[2]]
[1] 4
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好...
但是如果代码i + 2
保存在文件中addition.R
并且我使用source()
那时调用该文件
> foreach(i = 1:2) %dopar%{
+ source("addition.R")
+ }
Error in { : task 1 failed - "object 'i' not found"
Run Code Online (Sandbox Code Playgroud)
Sos*_*sel 11
我不能完全重现你的玩具,但我有一个熟悉的问题,我可以通过以下方式解决:
source(file, local = TRUE)
Run Code Online (Sandbox Code Playgroud)
它应解析本地环境中的源,即识别i.
尼斯的评论和索塞尔的回答已经解决了这个问题; 当调用source(file)
它默认为source(file, local = FALSE)
,这意味着源文件中的代码正在全局环境("用户的工作区")中进行评估,并且参见 ?source
.请注意,i
全局环境中没有变量.解决方案是确保文件来源于调用它的环境,即使用source(file, local = TRUE)
.
library("foreach")
y <- foreach(i = 1:2) %dopar% {
i + 2
}
str(y)
doMC::registerDoMC(cores = 2L)
y <- foreach(i = 1:2) %dopar% {
source("addition.R", local = TRUE)
}
str(y)
Run Code Online (Sandbox Code Playgroud)
for()
循环相同问题的示例:source()
在全局环境中评估的事实与调用环境不同,其中i
生命也可以通过在除了全局之外的另一个环境中运行for循环来使用常规for循环来说明,例如在函数内部或通过:
local({
for(i in 1:2) {
source("addition.R")
}
})
Run Code Online (Sandbox Code Playgroud)
这使:
Error in eval(ei, envir) : object 'i' not found
Run Code Online (Sandbox Code Playgroud)
现在,上面的原因是foreach(i = 1:2) %dopar% { source("addition.R") }
,registerDoSEQ()
当且仅当从全局环境调用时,是因为foreach迭代在调用环境中进行评估,调用环境是全局环境,即source()
使用的环境.但是,如果使用它local(foreach(i = 1:2) %dopar% { ... })
也会类似于上述local(for(i in 1:2) { ... })
调用失败.
总之:没有什么魔法发生,但要理解它有点单调乏味.