有没有一种方法可以并行操作
R
中的对象?我知道parallel
中的mclapply
会分叉进程并将工作区内容复制到每个进程中。我希望我的核心能够在对象上执行独立的作业,而无需拆分和组合结果。一个用例是将数据框中的所有numeric
列更改为并行的factor
列。另一个用例是对具有大量级别的数据框中的因子进行分箱。我尝试这样做的主要原因是1)避免耗尽内存和2)提高速度。
下面,对象b
是拆分数据框a
中的列然后在应用factor
之后将它们组合起来的结果。相反,我想直接操作对象a
。串行地,我能够通过foreach...%do%
循环的副作用将a
中的列转换为factor
类型。在并行中,我无法将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
mclapply(chunkify(dat, chunks = mc.cores), mc.cores = mc.cores, FUN = function(x) someFunction(x))
,其中chunkify
返回一个由dat
的chunks
子数据框组成的列表。我认为子进程只会使用大约3GB/mc.cores的内存)。 - lockedoffforeach
,并尝试修改其作用域之外的对象a
。在%do%(串行)的情况下,它可以工作(就像在for
循环中一样),而在%dopar%(并行)的情况下,则失败了。我仍在寻找一种在不复制、应用、收集的情况下并行地对对象进行操作的方法。 - lockedoffdata.table
时,结合foreach
循环并按照某个键值进行分割后,直接传递数据块非常高效。我相信data.table
是通过引用传递的。这非常依赖于具体的使用情况,但它帮助我解决了内存问题。 - Matt Weller