18

我对数据帧有许多操作,我想加快使用这些操作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 解决方案?

4

2 回答 2

16

只需使用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
于 2011-02-24T21:59:06.890 回答
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 
于 2011-02-24T21:58:19.460 回答