5

目的は、データ フレーム内の因子/文字列変数のインジケーターを作成することです。そのデータフレームの行数は 2mm を超えており、Windows で R を実行すると、.parallel=T で plyr を使用するオプションがありません。そこで、plyr と reshape2 を使用して「分割統治」ルートを採用しています。

メルトとキャストを実行するとメモリが不足し、

ddply( idata.frame(items) , c("ID") , function(x){
       (    colSums( model.matrix( ~ x$element - 1) ) > 0   )
} , .progress="text" )    

また

ddply( idata.frame(items) , c("ID") , function(x){
           (    elements %in% x$element   )
    } , .progress="text" )  

時間がかかります。最速のアプローチは、以下の tapply を呼び出すことです。これをスピードアップする方法はありますか?%in% ステートメントは、model.matrix 呼び出しよりも高速に実行されます。ありがとう。

set.seed(123)

dd <- data.frame(
  id  = sample( 1:5, size=10 , replace=T ) ,
  prd = letters[sample( 1:5, size=10 , replace=T )]
  )

prds <- unique(dd$prd)

tapply( dd$prd , dd$id , function(x) prds %in% x )
4

3 に答える 3

4

この問題については、パッケージbigmemorybigtabulateあなたの友達かもしれません。もう少し野心的な例を次に示します。

library(bigmemory)
library(bigtabulate)

set.seed(123)

dd <- data.frame(
  id = sample( 1:15, size=2e6 , replace=T ), 
  prd = letters[sample( 1:15, size=2e6 , replace=T )]
  )

prds <- unique(dd$prd)

benchmark(
bigtable(dd,c(1,2))>0,
table(dd[,1],dd[,2])>0,
xtabs(~id+prd,data=dd)>0,
tapply( dd$prd , dd$id , function(x) prds %in% x )
)

そして、ベンチマークの結果 (私は常に新しいことを学んでいます):

                                            test replications elapsed relative user.self sys.self user.child sys.child
1                      bigtable(dd, c(1, 2)) > 0          100  54.401 1.000000    51.759    3.817          0         0
2                    table(dd[, 1], dd[, 2]) > 0          100 112.361 2.065422   107.526    6.614          0         0
4 tapply(dd$prd, dd$id, function(x) prds %in% x)          100 178.308 3.277660   166.544   13.275          0         0
3                xtabs(~id + prd, data = dd) > 0          100 229.435 4.217478   217.014   16.660          0         0

そして、それはbigtableかなりの量で勝っていることを示しています。結果は、すべての prd がすべての ID に?bigtableあるということですが、結果の形式の詳細については、を参照してください。

于 2012-03-26T20:50:44.960 に答える
2

レベルの数、ID の数などに関して、問題がどのようにスケールするかをもう少し言えますか (レベルの数を固定しておくと、十分な数の個人に対して、計算している指標マトリックスはすべて TRUE に近づきます) /all 1 ...)? 私はそれxtabsがより速いと思っていましたが、このサイズの例ではありません...

library(rbenchmark)
benchmark(
          tapply( dd$prd , dd$id , function(x) prds %in% x ),
          xtabs(~id+prd,data=dd)>0)

     test        replications elapsed relative 
1 tapply(...)             100   0.053 1.000000
2 xtabs(...) > 0          100   0.120 2.264151  
于 2012-03-26T19:57:32.950 に答える
1

あなたの%in%関数の使用は私には逆に思えます。また、データの各行の真/偽の結果が必要な場合は、%in% をベクトル演算として使用するか、 ave. ここでは必要ありませんが、すべてのアイテムに適用する必要があるより複雑な関数がある場合は、これを使用することをお勧めします。

set.seed(123)

dd <- data.frame(
  id  = sample( 1:5, size=10 , replace=T ) ,
  prd = letters[sample( 1:5, size=10 , replace=T )]
  )

prds <- unique(dd$prd)
target.prds <- prds[1:2]
dd$prd.in.trgt <- with( dd, prd %in% target.prds)
于 2012-03-26T19:50:58.690 に答える