2012-10-19 7 views
7

私は2つのベクトルegを持っています。私はeの各要素について、gの要素の割合が小さいことを知りたいと思います。 Rでこれを実装する1つの方法は次のとおりです。大eまたはgサプリーコールでR内で使用する高速化機能

set.seed(21) 
e <- rnorm(1e4) 
g <- rnorm(1e4) 
mf <- function(p,v) {100*length(which(v<=p))/length(v)} 
mf.out <- sapply(X=e, FUN=mf, v=g) 

、これは実行するために多くの時間を要します。このコードを変更してこのコードをより速く実行するにはどうすればよいですか?

注:上記のmf関数は、dismoパッケージのmess関数のコードに基づいています。

+0

あなたが Dason

+0

ダソン氏に感謝しますが、それは 'sapply'の代わりに – Paulo

+0

' vapply'がおそらく役に立ちます。 –

答えて

8

これは遅い理由は、あなたの関数をlength(e)回呼び出しているからです。小さなベクトルでは大きな違いはありませんが、R関数呼び出しからのオーバーヘッドは本当に大きなベクトルで加算され始めます。

通常、あなたがコンパイルされたコードにこれを移動する必要があるだろうが、幸いにもあなたはfindIntervalを使用することができます。

set.seed(21) 
e <- rnorm(1e4) 
g <- rnorm(1e4) 
O <- findInterval(e,sort(g))/length(g) 

# Now for some timings: 
f <- function(p,v) mean(v<=p) 
system.time(o <- sapply(e, f, g)) 
# user system elapsed 
# 0.95 0.03 0.98 
system.time(O <- findInterval(e,sort(g))/length(g)) 
# user system elapsed 
#  0  0  0 
identical(o,O) # may be FALSE 
all.equal(o,O) # should be TRUE 

# How fast is this on large vectors? 
set.seed(21) 
e <- rnorm(1e7) 
g <- rnorm(1e7) 
system.time(O <- findInterval(e,sort(g))/length(g)) 
# user system elapsed 
# 22.08 0.08 22.31 
+0

ありがとう@ジョシュア、素晴らしい答え。速度の向上は素晴らしいです。元の関数と同じ出力を得るための小さな修正:findInterval(e、sort(g))/ length(g) – Paulo

関連する問題