R:将数据帧的每一行转换为列表项

时间:2011-02-24 21:32:20

标签: r parallel-processing multicore dataframe plyr

我对数据框进行了大量操作,我希望使用mclapply()或其他类似lapply()的函数加快速度。我最容易解决这个问题的方法之一是使数据帧的每一行成为列表中的一个小数据帧。我可以使用plyr这样轻松地完成此操作:

df <- data.frame( a=rnorm(1e4), b=rnorm(1e4))
require(plyr)
system.time(myList <- alply( df, 1, function(x) data.frame(x) ))

一旦我将数据作为列表,我可以轻松地执行以下操作:

mclapply( myList, function(x) doSomething(x$a) )

这很有效,但我有很多数据,adply()步骤很慢。我尝试在adply步骤中使用多核并行后端,但它从未使用过多个处理器,即使我已经注册了8.我很怀疑并行选项可能无法解决此类问题。

有关如何加快速度的任何提示?也许是基础R解决方案?

2 个答案:

答案 0 :(得分:15)

只需使用split即可。它比您的adply行快几倍。

> system.time(myList <- alply( df, 1, function(x) data.frame(x) ))
   user  system elapsed 
   7.53    0.00    7.57 
> system.time( splitList <- split(df, 1:NROW(df)) )
   user  system elapsed 
   1.73    0.00    1.74 
> 

我怀疑adply上的并行后端仅用于功能评估(不进行拆分和重新组合)。

更新:
如果您可以将data.frame转换为矩阵,则下面的解决方案将是超快速的。您可以使用split,但它会删除名称并在每个列表元素中返回一个向量。

> m <- as.matrix(df)
> system.time( matrixList <- lapply(1:NROW(m), function(i) m[i,,drop=FALSE]) )
   user  system elapsed 
   0.02    0.00    0.02
> str(matrixList[[1]])
 num [1, 1:2] -0.0956 -1.5887
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "a" "b"
> system.time( matrixSplitList <- split(m, 1:NROW(m)) )
   user  system elapsed 
   0.01    0.00    0.02 
> str(matrixSplitList[[1]])
 num [1:2] -0.0956 -1.5887

答案 1 :(得分:6)

这个怎么样?

jdList <- split(df, 1:nrow(df))

> class(jdList[[1]])
[1] "data.frame"

> system.time(jdList <- split(df, 1:nrow(df)))
   user  system elapsed 
   1.67    0.02    1.70 
> system.time(myList <- alply( df, 1, function(x) data.frame(x) ))
   user  system elapsed 
    7.2     0.0     7.3