18

mclapply()データフレームに対して、他の同様の関数を使用して高速化したい操作がいくつかありlapply()ます。これに取り組む最も簡単な方法の1つは、データフレームの各行をリスト内の小さなデータフレームにすることです。私はこれを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

Just use split. It's a few times faster than your adply line.

> 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 
> 

I suspect the parallel backend on adply is only for function evaluation (not splitting and re-combining).

UPDATE:
If you can convert your data.frame to a matrix, the solution below will be über-fast. You may be able to use split, but it will drop names and return a vector in each list element.

> 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

How about this?

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 に答える