Search code examples
rloopsfor-loopforeachdoparallel

Unwanted result from parallel computation with forerach


I want to print a message after every 5 iterations in a loop. This works in a base R loop as follows:

vec = c() # empty vector
for (i in 1:100) {
        
        s = sqrt(i)
        vec = c(vec, s)
        if (i %% 5 == 0) {
                print(paste0("Iteration number: ", i, " finished running"))
        }
        
}

I want to be able to do the same using paralel computation with forerach. So far I have done the following:

vec = c() # empty vector
library(doParallel); library(foreach)
ncores = detectCores() # number of cores in my computer
registerDoParallel(ncores)
foreach (i = 1:100) %dopar% {
        
        s = sqrt(i)
        vec = c(vec, s)
        if (i %% 5 == 0) {
                print(paste0("Iteration number: ", i, " finished running"))
        }
        
}
stopImplicitCluster()

However, it does not work the way I want. It also prints NULLs for some reason in a "list-like" format. How can I achieve the same result from the base R loop in the forerach approach?


Solution

  • If the messages printed on each multiple of 5 are strictly not need, the following will create two identical vectors.
    Note that I create vec beforehand and that I use message in the loop.

    vec <- numeric(100)
    for (i in 1:100) {
      vec[i] <- sqrt(i)
      if (i %% 5 == 0) {
        message(paste0("Iteration number: ", i, " finished running"))
      }
    }
    
    library(doParallel)
    library(foreach)
    
    ncores <- detectCores() # number of cores in my computer
    registerDoParallel(ncores)
    
    vec2 <- foreach(i = 1:100, .combine = c) %dopar% {
      sqrt(i)
    }
    stopImplicitCluster()
    
    identical(vec, vec2)
    #[1] TRUE