rbind可以在R中并行吗?

rbind可以在R中并行吗?,r,R,当我坐在这里等待一些R脚本运行时…我想知道。。。有没有办法在R中并行rbind 我经常坐着等待这个调用完成,因为我处理大量数据 do.call("rbind", LIST) 我怀疑你能通过并行化更快地实现这一点:除了你可能必须自己编写之外(第一个线程是rbinds项目1和2,而第二个线程是rbinds项目3和4,等等,当它们完成时,结果是“反弹”,类似这样的-我看不到一种非C方式来改进这一点),这将涉及在线程之间复制大量数据,这通常是一开始就会变慢的事情 在C中,您可以在线程之间共享对象,这样

当我坐在这里等待一些R脚本运行时…我想知道。。。有没有办法在R中并行rbind

我经常坐着等待这个调用完成,因为我处理大量数据

do.call("rbind", LIST)

我怀疑你能通过并行化更快地实现这一点:除了你可能必须自己编写之外(第一个线程是rbinds项目1和2,而第二个线程是rbinds项目3和4,等等,当它们完成时,结果是“反弹”,类似这样的-我看不到一种非C方式来改进这一点),这将涉及在线程之间复制大量数据,这通常是一开始就会变慢的事情

在C中,您可以在线程之间共享对象,这样您就可以让所有线程在同一内存中写入。祝你好运:——)


最后,作为旁白:rbinding data.frames非常慢。如果您事先知道所有data.frames的结构完全相同,并且它不包含纯字符列,那么您可能可以使用来自的技巧。如果您的data.frame包含字符列,我想您最好先单独处理这些(
do.call(c,lappy(LIST,“[[”,“myCharColName”))
),然后对其余部分执行该技巧,然后再重新组合它们。

到目前为止,我还没有找到并行处理的方法。但是对于我的数据集(这是一个大约1500个数据帧的列表,共450万行)下面的代码片段似乎有帮助:

while(length(lst) > 1) {
    idxlst <- seq(from=1, to=length(lst), by=2)

    lst <- lapply(idxlst, function(i) {
        if(i==length(lst)) { return(lst[[i]]) }

        return(rbind(lst[[i]], lst[[i+1]]))
    })
}
while(长度(lst)>1){

idxlst这里有一个解决方案,它自然扩展到rbind.fill、merge和其他dataframe列表函数:

但就像我所有的答案/问题一样:)

require(降雪)
要求(rbenchmark)

rbinder因为您说过要rbind
data.frame
对象,所以您应该使用
data.table
包。它有一个名为
rbindlist
的函数,可以极大地增强
rbind
。我不是100%确定,但我敢打赌
rbind
的任何使用都会在
rbindlist
不起作用时触发复制T 无论如何,
data.table
是一个
data.frame
,所以您不需要尝试任何东西

编辑:

library(data.table)
system.time(dt <- rbindlist(pieces))
utilisateur     système      écoulé 
       0.12        0.00        0.13 
tables()
     NAME  NROW MB COLS                        KEY
[1,] dt   1,000 8  X1,X2,X3,X4,X5,X6,X7,X8,...    
Total: 8MB
库(data.table)

system.time(dt这在@Dominik的答案上扩展

我们可以使用并行包中的mclappy来进一步提高速度。另外,rbind.fill比rbind做得更好,所以下面是改进的代码。 注意:这只适用于mac/linux。Windows不支持McLappy。 编辑:如果您想查看进度,请取消对打印(i)行的注释,并确保从终端而不是从RStudio运行。从并行进程打印到RStudio会有点混乱RStudio

library(parallel)
rbind.fill.parallel <- function(list){
  while(length(list) > 1) {
    idxlst <- seq(from=1, to=length(list), by=2)

    list <- mclapply(idxlst, function(i) {
      #print(i) #uncomment this if you want to see progress
      if(i==length(list)) { return(list[[i]]) }
      return(rbind.fill(list[[i]], list[[i+1]]))
    })
  }
}
库(并行)
rbind.fill.parallel 1){

idxlst看起来很多人已经很好地回答了这个问题,但是如果有人提出了这个问题,下面是一个针对非data.table/data.frame-esque对象的并行rbind版本:

rbind.parallel <- function(list,ncore)
  {
  library(parallel)
  do.call.rbind<-function(x){do.call(rbind,x)}
  cl<-makeCluster(ncore)
  list.split<-split(list,rep(1:ncore,length(list)+1)[1:length(list)])
  list.join<-parLapply(cl,list.split,do.call.rbind)
  stopCluster(cl)
  list.out<-do.call(rbind,list.join)
  return(list.out)
  }

plyr软件包中的
rbind.parallel宣传它的运行速度比base
rbind
快得多。也许你会看到一些性能上的颠簸。如果你添加一些具有代表性的样本数据,人们可以提供其他解决方案以及测试时间的基准。在
列表
中有什么类型的对象(矩阵、data.frame等)?列表中有什么类型的对象?Data.frames.dam,它实际上运行得更快!@Arun,这是一个错误,我已经修复了,但它似乎没有保存。你也可以轻松地将其扩展到
rbindlist
或其他基于列表的技术。我只是使用Rs standard
rbind
来方便地证明概念。@Arun,这不是我的意思。我我从不认为我的并行化解决方案是最快的解决方案。我只是用“是”回答了这个问题:“rbind可以并行化吗?”您可以将这种方法用于不同的函数。通过
rbindlist
解决方案,我们很高兴看到它通过并行化得到了改进。这可能不是因为将库/函数“读到核心”比仅仅绑定10公里的帧要花更多的时间。但是10万、1米、10米呢?我现在在我的夏季别墅里,有一台旧的macbook。所以我要到周一才能正确尝试。Ha必须是计算史上速度最快的!在我这方面,从几个小时到不到一秒钟。
rbind.parallel <- function(list,ncore)
  {
  library(parallel)
  do.call.rbind<-function(x){do.call(rbind,x)}
  cl<-makeCluster(ncore)
  list.split<-split(list,rep(1:ncore,length(list)+1)[1:length(list)])
  list.join<-parLapply(cl,list.split,do.call.rbind)
  stopCluster(cl)
  list.out<-do.call(rbind,list.join)
  return(list.out)
  }