r - 使用 mclapply、foreach 或 [r] 中的其他东西并行操作对象?

标签 r memory foreach parallel-processing fork

有没有办法并行操作 R 中的对象?我了解 mclapplyparallel 中 fork 进程并将工作区内容复制到每个进程。相反,我希望让我的核心在一个对象上执行独立的工作,而不必拆分和组合结果。一个用例是将 data.frame 中的所有 numeric 列并行更改为 factor 列。另一个用例是 data.frame 中具有大量级别的分箱因素。我尝试这样做的主要原因是 1) 避免内存不足和 2) 提高速度。

下面,对象b是在data.frame a中拆分列,然后在应用factor后组合它们的结果。相反,我想直接对对象 a 进行操作。在序列中,我能够将 a 中的列转换为 factor 类型作为 foreach...%do% 的副作用环形。同时,作为副作用,我无法将 a 的列转换为 factor 类型,因为(据我所知)在 foreach... %dopar%a 指的是每个派生进程的本地对象。

R 中是否有一个包可以让我这样做?

a <- data.frame(b=c(1,1,2,2), c=c(2,2,3,3))
str(a)

> str(a)
'data.frame':   4 obs. of  2 variables:
 $ b: num  1 1 2 2
 $ c: num  2 2 3 3

#serial
b <-
  foreach (i = iter(1:ncol(a)), .combine = data.frame) %do% {
    a[,i] <- factor(a[,i])
  }
str(a)
str(b)

> str(a)
'data.frame':   4 obs. of  2 variables:
 $ b: Factor w/ 2 levels "1","2": 1 1 2 2
 $ c: Factor w/ 2 levels "2","3": 1 1 2 2
> str(b)
'data.frame':   4 obs. of  2 variables:
 $ result.1: Factor w/ 2 levels "1","2": 1 1 2 2
 $ result.2: Factor w/ 2 levels "2","3": 1 1 2 2

#parallel
a <- data.frame(b=c(1,1,2,2), c=c(2,2,3,3))
b <-
  foreach (i = iter(1:ncol(a)), .combine = data.frame) %dopar% {
    a[,i] <- factor(a[,i])
  }
str(a)
str(b)

> str(a)
'data.frame':   4 obs. of  2 variables:
 $ b: num  1 1 2 2
 $ c: num  2 2 3 3
> str(b)
'data.frame':   4 obs. of  2 variables:
 $ result.1: Factor w/ 2 levels "1","2": 1 1 2 2
 $ result.2: Factor w/ 2 levels "2","3": 1 1 2 2

最佳答案

首先,您必须知道 R 是(通常)按值调用,因此无论您做什么,您最终都会得到数据框的临时副本。这也适用于 apply 系列的普通版本。一旦你改变了函数内部的东西,对象首先被复制。

也就是说,mclapply 不会将完整的工作区内容复制到子进程。据我了解,这些进程共享相同的内存内容,并且仅在对其进行修改后才复制内容。这或多或少取决于 R 所做的事情。

如果您仍然不相信这一点,您可以使用集群方法并尝试 parLapplyparallel 包中的 friend 。这不是基于 fork ,而是基于节点集群。您可以在此处将核心视为节点。在这种情况下,您必须使用 clusterExport() 从计算所需的工作区中显式导出变量。我不确定这一点,但我怀疑这确实会创建一个副本。对于其余部分,parLapply 仅将它处理的元素复制到不同的集群。同样,这与 lapply 默认情况下所做的相同。

使用数据框 a,您可以执行以下操作:

> require(parallel)
> cl <- makeCluster(2)
> b <- parLapply(cl,a,as.factor)
> str(as.data.frame(b))
'data.frame':   4 obs. of  2 variables:
 $ b: Factor w/ 2 levels "1","2": 1 1 2 2
 $ c: Factor w/ 2 levels "2","3": 1 1 2 2
> stopCluster(cl)       

关于r - 使用 mclapply、foreach 或 [r] 中的其他东西并行操作对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11036702/

相关文章:

c# - 内存不足异常,即使有 30 GB 内存可用

C 程序内存使用 - 报告的内存多于分配的内存

r - 如何使用 Torque/MOAB 调度程序设置 doSNOW 和 SOCK 集群?

R/dplyr : Remove all rows in imported csv data frame that have NA entries only

r - 使用 knitr 和 knitExtra 编织时找不到 kable_input

c++ - 读取进程内存

linux - 使用 foreach 循环时不会出现列的最大值

php - 返回数组中大于X的数字

r - 计算 R 中的平均时间

r - 在 RStudio 中使用 Makefile