有没有办法同时对R
中的对象进行操作?我理解mclapply
parallel
中的numeric
进程并将工作空间内容复制到每个进程。相反,我希望让我的核心在一个对象上执行独立的工作,而不必拆分和组合结果。用例是将data.frame中的所有factor
列并行更改为b
列。另一个用例是具有大量级别的data.frame中的分箱因子。我尝试这样做的主要原因是1)避免内存不足和2)提高速度。
下面,对象a
是在data.frame 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
中有一个包可以让我这样做吗?
{{1}}
答案 0 :(得分:4)
首先,您必须知道R(通常)call by value
,所以无论您做什么,您最终都会得到数据框的临时副本。这适用于apply系列的正常版本。一旦你在函数内部更改了某些内容,就会先复制该对象。
这就是说,mclapply
不会将完整的工作区内容复制到子进程。据我所知,进程共享相同的内存内容,只有在对内容进行修改后才复制内容。无论如何,R或多或少都会降低。
如果您仍然不相信这一点,可以使用群集方法并尝试parLapply
和parallel
包中的朋友。这不是基于分叉,而是基于节点集群。您可以在此处将核心视为节点。在这种情况下,您必须使用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)