并行for循环输出错误

时间:2018-10-11 19:28:59

标签: r

我正在尝试使用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行数据框。我想知道为什么我的代码是错误的。

2 个答案:

答案 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

因此,需要返回所有感兴趣的变量。在上面的示例中,ij的值作为矩阵返回。

> out
         i  j
result.1 1 10
result.2 2 20
result.3 3 30
result.4 4 40