将`mclapply`结果放回data.frame

gre*_*ane 5 parallel-processing r lapply

我有一个非常大的 data.frame,我想应用一个相当复杂的函数,计算一个新列.我想要并行完成.这类似于r listserve上发布的问题,但第一个答案是错误的,第二个答案是无益的.

由于parallel包装的原因,我已经弄明白了,除了如何将输出重新放回数据框.这是一个显示我所得到的MWE:

library(parallel)

# Example Data
data <- data.frame(a = rnorm(200), b = rnorm(200),  
                   group = sample(letters, 200, replace = TRUE))

# Break into list
datagroup <- split(data, factor(data$group))

# execute on each element in parallel
options(mc.cores = detectCores())
output <- mclapply(datagroup, function(x) x$a*x$b)
Run Code Online (Sandbox Code Playgroud)

结果output是一个数字向量列表.我需要将它们添加到我可以添加的列中data.我一直在寻找do.call(cbind, ...),但我有两个名称相同的列表,而不是我加入的单个列表.melt(output)给我一个向量,但它的行与...的顺序不同data.

tal*_*lat 5

从评论转换为回答..

这似乎有效:

data <- 
  do.call(
    rbind, mclapply(
      split(data, data$group), 
       function(x){
         z <- x$a*x$b
         x <- as.data.frame(cbind(x, newcol = z))
         return(x)
         }))
rownames(data) <- seq_len(nrow(data))
head(data)
#           a          b group      newcol
#1 -0.6482428  1.8136254     a -1.17566963
#2  0.4397603  1.3859759     a  0.60949714
#3 -0.6426944  1.5086339     a -0.96959055
#4 -1.2913493 -2.3984527     a  3.09724030
#5  0.2260140  0.1107935     a  0.02504087
#6  2.1555370 -0.7858066     a -1.69383520
Run Code Online (Sandbox Code Playgroud)

由于您正在使用“非常大”的 data.frame(大概有多大?),您是否考虑过使用其中之一dplyrdata.table用于您的工作?对于大型数据集,使用其中之一的性能可能比使用mclapply. 相当于:

library(dplyr)
data %>%
  group_by(group) %>%
  mutate(newcol = a * b)

library(data.table) 
setDT(data)[, newcol := a*b, by=group]
Run Code Online (Sandbox Code Playgroud)