2016-07-18 4 views
2

Rのhist(x, breaks=XXX, plot=FALSE)$count関数のより高速な代替策を探しています。他の出力は必要ありません。 sapply呼び出しで使用します。この関数が呼び出される回数は100万回です)。

x = runif(100000000, 2.5, 2.6) 
bincounts = hist(x, breaks=seq(0,3,length.out=100), plot=FALSE)$count 

どのような考えですか?

+0

は多分 'hist.default'ためのコードをチェックアウトし、必要のない部分を放り出しますか?たとえば、有限個数はありませんか? 'hist'はそれをチェックします。 – Zelazny7

+0

これは、CALL(C_BinCount、x、fuzzybreaks、right、include.lowest)への呼び出しを行うことです。通常のスクリプトから呼び出すにはどうすればいいですか?私は有限の値しか持っていません。 –

+0

各繰り返しで、新しい 'x'を作成しているのか、同じ' x'を使っていますか?あなたの 'sapply'の間に' x'が同じであれば、最初に 'sort'を考えてください。一般的に、' hist'/'findInterval'のどちらかで計算時間が短縮されます。 –

答えて

3

tablecutを使用して最初の試み:

table(cut(x, breaks=seq(0,3,length.out=100))) 

それは余分な出力を回避できますが、私のコンピュータ上で約34秒かかる:histのための3.5秒に比べ

system.time(table(cut(x, breaks=seq(0,3,length.out=100)))) 
    user system elapsed 
34.148 0.532 34.696 

を:

system.time(hist(x, breaks=seq(0,3,length.out=100), plot=FALSE)$count) 
    user system elapsed 
    3.448 0.156 3.605 

を使用

.bincode少し速くhistよりも動作します:

tablulateを使用して
tabulate(.bincode(x, breaks=seq(0,3,length.out=100)), nbins=100) 

system.time(tabulate(.bincode(x, breaks=seq(0,3,length.out=100))), nbins=100) 
    user system elapsed 
    3.084 0.024 3.107 

findIntervaltablecutのパフォーマンスが著しく向上する相対を提供し、histにOK改善の相対を持っています

tabulate(findInterval(x, vec=seq(0,3,length.out=100)), nbins=100) 

system.time(tabulate(findInterval(x, vec=seq(0,3,length.out=100))), nbins=100) 
    user system elapsed 
    2.044 0.012 2.055 
+0

はい、しかしこの問題は、それがsuuuper slow ...だから私はiteratiteする必要がありますので、私のためのオプションではない百万回... –

+0

はい。 'hist'は約10倍速くなっているようです。私はスピードアップを見つけることができるかどうかを見るために、今、いくつかの選択肢を試しています。 – lmo

+0

Microsoft Rオープン3.2.5で上記のソリューションを実行すると、速度がはるかに向上します。 'user 1.34'' system 0.09''が '1.43'経過しました。ただ一つの選択肢かもしれない。 – user5249203

3

あなたの最善の策は、ちょうど切り取ることですすべてのオーバーヘッドはhist.defaultです。

nB1 <- 99 
delt <- 3/nB1 
fuzz <- 1e-7 * c(-delt, rep.int(delt, nB1)) 
breaks <- seq(0, 3, by = delt) + fuzz 

.Call(graphics:::C_BinCount, x, breaks, TRUE, TRUE) 

私は正確にどのようにhist作品(と小さいベクトルでテスト - n = 100の代わりに、1000000)の感触を得るためにdebugonce(hist.default)を実行することによって、このまで切り詰め。比較

x = runif(100, 2.5, 2.6) 
y1 <- .Call(graphics:::C_BinCount, x, breaks + fuzz, TRUE, TRUE) 
y2 <- hist(x, breaks=seq(0,3,length.out=100), plot=FALSE)$count 
identical(y1, y2) 
# [1] TRUE 
+0

@TomWenseleersこれは遅いというのは不思議ではありません...なぜ' hist'では 'tabulate(findInterval ) 'もしそれが良ければ?私は、 'graphics :::'を使うことにかなりのオーバーヘッドがあるのだろうかと思っています... – MichaelChirico