3

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

下面,objectb是在 data.frame 中拆分列,a然后在 apply 后合并它们的结果factor。相反,我想直接对 object 进行操作a。在串行中,作为循环的副作用,我能够将列转换a为类型。同时,作为副作用,我无法将 的列转换为类型,因为(据我所知)内部的,指的是每个衍生进程的本地对象。factorforeach...%do%afactorforeach...%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
4

1 回答 1

5

首先,您必须知道 R 是 (generally) 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)       
于 2012-06-14T16:20:50.793 回答