了解foreach

时间:2018-10-12 18:13:30

标签: r

我不熟悉使用foreach并行处理for循环,并且难以理解它的工作原理。作为练习的示例,我基于数据框(输入)创建了一个简单列表(input2)。我尝试通过遍历h和j来计算b。

library(doParallel)
library(foreach)
library(dplyr)

input <- data.frame(matrix(rnorm(200*200, 0, .5), ncol=200))
input[input <=0] =0
input['X201'] <- seq(from = 0, to = 20, length.out = 10)
input <- input %>% select(c(X201, 1:200))
input2 <- split(input, f= input$X201)

a = 0
b= 0
cl <- parallel::makeCluster(20)
doParallel::registerDoParallel(cl)
tm1 <- system.time(
  y <- 
    foreach (h = length(input2),.combine = 'cbind') %:%
    foreach (j = nrow(input2[[h]]),.combine = 'c',packages = 'foreach') %dopar%{
      a = input2[[h]][j,3]
      b = b + a
    } 

)
parallel::stopCluster(cl)
registerDoSEQ()
print("Cluster stopped.")

y大约为0.55(确切的值取决于生成的随机数1),它是input2[[10]][20,3]的值,而不是我想要的累积值。我检查了foreach软件包的手册,但仍然不确定我是否完全了解foreach函数的机制。

1 个答案:

答案 0 :(得分:3)

R foreach返回结果,而是允许更改外部变量。因此,不要期望a,b被正确更新。

尝试以下

cl <- parallel::makeCluster(20)
doParallel::registerDoParallel(cl)

tm2 <- system.time(
results <- foreach(h = (1:length(input2)), .combine = "c") %dopar%{
    sum( input2[[h]][1:nrow(input2[[h]]),3])
},
b <- sum(results[1:length(results)])
)
parallel::stopCluster(cl)
registerDoSEQ()
b
tm2