我正在尝试使用foreach包并行处理嵌套的for循环。但是,尽管速度要快得多,但却无法给出正确的答案。这个特定的嵌套for循环的想法非常简单。最里面的嵌套循环的结果(一个数)被添加到第二层循环,第二层循环被添加到第三层循环。以下是可复制的数据:
input <- data.frame(matrix(rnorm(100*100, 1, .5), ncol=100))
input[input <0] =0
input2 <- split(input, f=input$X201)
d= 0
n= 0
j = 1
k = 1
f = 0
s= 0
cl <- parallel::makeCluster(20)
doParallel::registerDoParallel(cl)
tm1 <- system.time(
results2 <- foreach(h = (1:length(input2)),.combine = 'c')%dopar%{
return ( for (j in (1:nrow(input2[[h]]))){
for (k in (1:nrow(input2[[h]]))){
if (k != j) {
for (i in (2:ncol(input2[[h]]))){
if (input2[[h]][j,i] !=0){
n= n+ (input2[[h]][j,i] * input2[[h]][k, i])
d= d+ input2[[h]][j, i] * input2[[h]][j, i]
}else {
n= n
}
}
f= f+ n/d* input2[[h]][k, 1]
}
n= 0
d= 0
}
s= s+ f* input2[[h]][j,1]
k = 1
f = 0
}
)
}
)
parallel::stopCluster(cl)
registerDoSEQ()
print("Cluster stopped.")
results2
最终输出results2
为Null。另外,在运行foreach循环之后,我发现只有i为8,h为6,而k和j仅为1,这似乎是错误的,因为我希望k随时与j不相等(如代码所示),并且我希望h为10(因为列表中有10个元素)。我也希望我是20,因为在每个元素中,有20行数据框。我想知道为什么我的代码是错误的。
答案 0 :(得分:2)
R foreach返回结果,而是允许更改外部变量。因此,不要期望d,n被正确更新。将结果视为减少映射并为最顶层的for循环进行并行处理的一种方式。
答案 1 :(得分:0)
foreach()
不会在循环内更新变量。考虑以下示例:
library(foreach)
library(doParallel); registerDoParallel(2)
j <- 1
out <- foreach(i=1:4, .combine=rbind) %dopar% {
j <- i*10
c(i=i, j=j)
}
j
未更新。
j
[1] 1
因此,需要返回所有感兴趣的变量。在上面的示例中,i
和j
的值作为矩阵返回。
> out
i j
result.1 1 10
result.2 2 20
result.3 3 30
result.4 4 40