Foreach循环无法找到对象 [英] Foreach loop unable to find object
问题描述
$ b 示例:
library(parallel)
library(foreach)
library(stats)
#create cluster
clu < - makeCluster(detectCores() - 1)
registerDoParallel(clu,cores = detectCores() - 1)
bar< -c(a,b,c在这个例子中,期望的输出是一个包含十个数字的列表,这个列表包含十个数字b,d)
rab <-c(2,3)
bar.name < - bar
#时间
bar [rab]
#或
eval(parse(text = paste(bar.name,[rab],sep =)))
foo< -foreach(m = 1:10,.packages = c(stats))%dopar%{
sink(foreach.txt)
print(bar.name)
print(parse(text = paste(bar.name,[rab],sep =)))
print(eval(parse(text = paste(bar.name,[rab] ),
foo.temp< -eval(parse(text = paste(bar.name,[rab],sep =)))
return( foo.temp)
sink
stopCluster
code $不过我明白了
{:task 1 failed - Object'bar'not found中的错误
我以为每个工作人员都得到了所有对象的工作空间副本。任何想法我做错了什么?
解决方案这听起来像一个糟糕的设计。使用 eval(parse())
。
为了得到一个变量 get()
有点安全,就像 get(bar.name)[rab]
。但是您仍然遇到环境问题。由于在 dopar 中没有变量 bar
或 rab
/ code>,它们不会被导出到 foreach
运行代码的环境中。你可以通过显式赋值foreach的 .exports =
参数来确定这些变量是否被导出。在这里,我更改为使用 get
,只需显式导出 bar
,因为 rab
现在包含在函数的框中。
foo <-foreach(m = 1:10,。 export = c(bar),.packages = c(stats))%dopar%{
get(bar.name)[rab]
}
一个比较好的方法不是指定一个变量名,而是指定一个名字列表的元素。例如
baz < - list(bar = letters [1:4],bob = letters [5:7])
然后您可以做
pre > baz.name< - bar
rab < - c(2,4)
foo < - foreach(m = 1:10,。 packages = c(stats))%dopar%{
baz [[baz.name]] [rab]
}
因为dopar可以看到变量 baz
, baz.name
, rab
您不必导出任何东西。
I am trying to use foreach with the parallel backend to speed up computation (of cross validation of an {AUCRF} random forest for feature selection, if this does matter). In the process of doing so i need to get a subset of a vector. The name of the vector can change but is accessible as character vector. I used the eval(parse()) construct(good idea?) to get a subset of the vector.
Example:
library(parallel)
library(foreach)
library(stats)
#create cluster
clu <- makeCluster(detectCores() - 1)
registerDoParallel(clu, cores = detectCores() - 1)
bar<-c("a","b","c","d")
rab<-c(2,3)
bar.name<-"bar"
#expected output in this example is a list containing ten times
bar[rab]
#or
eval(parse(text=paste(bar.name,"[rab]",sep="")))
foo<-foreach(m = 1:10, .packages = c("stats")) %dopar% {
sink("foreach.txt")
print(bar.name)
print(parse(text=paste(bar.name,"[rab]",sep="")))
print(eval(parse(text=paste(bar.name,"[rab]",sep=""))))
foo.temp<-eval(parse(text=paste(bar.name,"[rab]",sep="")))
return(foo.temp)
}
sink()
stopCluster(clu)
However i get the following error:
Error in { : task 1 failed - "Object 'bar' not found"
I thought that each worker is getting a copy of the workspace with all objects. Any idea what I'm doing wrong?
This sounds like a bad design. It's almost never necessary to use eval(parse())
.
To get a variable, get()
is somewhat safer, like get(bar.name)[rab]
. But you're still running into an environment issue here. Since you don't have the variables bar
or rab
in the body of the dopar
, they are not exported to the environment where foreach
is running the code. You can fix that with an explicit assignment of the .exports=
parameter of foreach to make sure those variables are exported. Here I change to use get
and only have to explicitly export bar
because rab
is now include in the box of the function.
foo<-foreach(m = 1:10, .export=c("bar"), .packages = c("stats")) %dopar% {
get(bar.name)[rab]
}
A better idea would be rather than specifying a variable name, specify an element of a named list. For example
baz <- list(bar=letters[1:4], bob=letters[5:7])
Then you could do
baz.name <- "bar"
rab <- c(2,4)
foo<-foreach(m = 1:10, .packages = c("stats")) %dopar% {
baz[[baz.name]][rab]
}
And because dopar can see the variables baz
, baz.name
, and rab
you don't have to export anything.
这篇关于Foreach循环无法找到对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!