代码之家  ›  专栏  ›  技术社区  ›  Roger

理解foreach

r
  •  4
  • Roger  · 技术社区  · 7 年前

    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.")
    

    0.55 (精确值取决于生成的随机数1),即 input2[[10]][20,3] ,不是我想要的累积值。我查看了foreach包的手册,但仍然不确定我是否完全理解foreach函数的机制。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Patrick    7 年前

    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