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

JD *_*ong 18 parallel-processing multicore r plyr dataframe

我对数据帧有很多操作,我想加快使用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) ))
Run Code Online (Sandbox Code Playgroud)

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

mclapply( myList, function(x) doSomething(x$a) )
Run Code Online (Sandbox Code Playgroud)

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

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

Jos*_*ich 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 
> 
Run Code Online (Sandbox Code Playgroud)

我怀疑并行后端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
Run Code Online (Sandbox Code Playgroud)


Rom*_*rik 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 
Run Code Online (Sandbox Code Playgroud)