8

次のように変換する 18 列と 11520 行の data.frame (ファイルへのリンク) があります。

library(plyr)
df.median<-ddply(data, .(groupname,starttime,fPhase,fCycle), 
                 numcolwise(median), na.rm=TRUE)

system.time() によると、実行にはこの程度の時間がかかります。

   user  system elapsed 
   5.16    0.00    5.17

この呼び出しは webapp の一部であるため、実行時間は非常に重要です。この呼び出しを高速化する方法はありますか?

4

6 に答える 6

9

使うだけaggregateでかなり速くなります...

> groupVars <- c("groupname","starttime","fPhase","fCycle")
> dataVars <- colnames(data)[ !(colnames(data) %in% c("location",groupVars)) ]
> 
> system.time(ag.median <- aggregate(data[,dataVars], data[,groupVars], median))
   user  system elapsed 
   1.89    0.00    1.89 
> system.time(df.median <- ddply(data, .(groupname,starttime,fPhase,fCycle), numcolwise(median), na.rm=TRUE))
   user  system elapsed 
   5.06    0.00    5.06 
> 
> ag.median <- ag.median[ do.call(order, ag.median[,groupVars]), colnames(df.median)]
> rownames(ag.median) <- 1:NROW(ag.median)
> 
> identical(ag.median, df.median)
[1] TRUE
于 2010-10-19T19:51:24.940 に答える
7

コメントからいくつかのポイントを要約するだけです:

  1. 最適化を開始する前に、「許容できる」パフォーマンスについてある程度理解しておく必要があります。必要なパフォーマンスに応じて、コードを改善する方法についてより具体的にすることができます。たとえば、あるしきい値では、Rの使用を停止し、コンパイルされた言語に移行する必要があります。
  2. 予想される実行時間が決まったら、既存のコードのプロファイルを作成して、潜在的なボトルネックを見つけることができます。Rには、Rprofを含むいくつかのメカニズムがあります([r] + rprofを検索した場合のstackoverflowの例があります)。
  3. plyrは、パフォーマンスではなく、主に使いやすさを目的として設計されています(ただし、最近のバージョンでは、パフォーマンスが大幅に向上しています)。一部の基本関数は、オーバーヘッドが少ないため、より高速です。@JDLongは、Hadleyの特殊な手法など、これらの問題のいくつかをカバーする素晴らしいスレッドを指摘しました。
于 2010-10-19T19:49:18.867 に答える
4

中央値を計算するときは、データの順序が重要です。データが最小から最大の順に並んでいる場合、計算は少し速くなります。

x <- 1:1e6
y <- sample(x)
system.time(for(i in 1:1e2) median(x))
   user  system elapsed 
   3.47    0.33    3.80

system.time(for(i in 1:1e2) median(y))
   user  system elapsed 
   5.03    0.26    5.29

新しいデータセットについては、インポート時に適切な列でデータを並べ替えます。既存のデータセットの場合、それらをバッチ ジョブとして (Web アプリの外部で) 並べ替えることができます。

于 2010-10-20T13:57:29.817 に答える
3

ジョシュアのソリューションに追加します。中央値の代わりに平均値を使用すると、計算をさらに 4 倍高速化できます。

> system.time(ag.median <- aggregate(data[,dataVars], data[,groupVars], median))
   user  system elapsed 
   3.472   0.020   3.615 
> system.time(ag.mean <- aggregate(data[,dataVars], data[,groupVars], mean))
   user  system elapsed 
   0.936   0.008   1.006 
于 2010-10-19T21:11:39.247 に答える
2

大規模なデータ フレーム (plyr パッケージの野球データ セット) に対して、標準ライブラリ関数 (「table」、「tapply」、「aggregate」など) と類似の plyr を使用していくつかの簡単な変換を行っただけです。 function--各インスタンスで、plyr が大幅に遅いことがわかりました。例えば、

> system.time(table(BB$year))
    user  system elapsed 
   0.007   0.002   0.009 

> system.time(ddply(BB, .(year), 'nrow'))
    user  system elapsed 
   0.183   0.005   0.189 

第二に、これがあなたのケースでパフォーマンスを向上させるかどうかは調査しませんでしたが、現在使用しているサイズ以上のデータ フレームについては、CRAN で利用可能なdata.tableライブラリを使用します。data.table オブジェクトを作成するだけでなく、既存の data.frame を data.tables に変換するのも簡単です。変換したい data.frame で data.table を呼び出すだけです。

dt1 = data.table(my_dataframe)
于 2010-10-19T20:57:43.940 に答える