The problem is that mclapply and mcmapply not intended to be used with functions that have side effects. Your function modifies the objects in the lists, but mclapply does not send the changed objects back to the main process: it only returns the values ββexplicitly returned by the function. This means that your results are lost when workers exit with mclapply .
Normally, I would change the code so as not to depend on side effects, and return objects that were changed. Here is one way to do this with clusterApply so that it also works in parallel on Windows:
library(R6) library(parallel) cl <- R6Class( classname = "cl", public = list( data = data.frame(NULL), initialize = function() invisible(self), insert = function(x) self$data <- rbind(self$data, x))) N <- 4L # number of entities i <- setNames(seq_len(N),paste0("n",seq_len(N))) set.seed(1) ldt <- lapply(i, function(i) data.frame(replicate(sample(3:10,1),sample(letters,1e5,rep=TRUE)))) nw <- 3 # number of workers clust <- makePSOCKcluster(nw) idx <- splitIndices(length(i), nw) nameslist <- lapply(idx, function(iv) names(i)[iv]) lcl4 <- do.call('c', clusterApply(clust, nameslist, function(nms, cl, ldt) { library(R6) lcl4 <- lapply(nms, function(n) cl$new()) names(lcl4) <- nms lapply(nms, FUN = function(n) lcl4[[n]]$insert(ldt[[n]])) lcl4 }, cl, ldt))
This method does not work if you want to create a list of objects once, and then change objects several times in parallel. This can also be done, but you must have regular employees. In this case, you receive the changed objects from the workers after completing all tasks. Unfortunately, mclapply does not use permanent workers, so in this case you should use cluster functions such as clusterApply . Here is one way to do this:
# Initialize the cluster workers clusterEvalQ(clust, library(R6)) clusterExport(clust, c('cl', 'ldt')) clusterApply(clust, nameslist, function(nms) { x <- lapply(nms, function(n) cl$new()) names(x) <- nms assign('lcl4', x, pos=.GlobalEnv) NULL })
This is very similar to the previous method, except that it divides the process into three stages: initializing the workers, completing the task, and finding the result. I also initialized the workers in a more traditional way using clusterExport and clusterEvalQ .