これまで提供されているソリューションは、すべてlogical(length(vec))
を作成し、これを完全または部分的にスキャンすることを意味しています。あなたが注意するように、ベクトルはソートされます。バイナリ検索を行うことでこれを悪用することができます。私は超賢いと思って、さらに高速化するためにCで実装しましたが、アルゴリズムの索引付けをデバッグするのに問題がありました(これは難しい部分です)。他の提案
f0 <- function(v) length(which(v < 0))
f1 <- function(v) sum(v < 0)
f2 <- function(v) which.min(v < 0) - 1L
と
> vec <- c(seq(-100,-1,length.out=1e6), rep(0,20), seq(1,100,length.out=1e6))
> identical(f0(vec), f1(vec))
[1] TRUE
> identical(f0(vec), f2(vec))
[1] TRUE
> identical(f0(vec), f3(vec))
[1] TRUE
> identical(f0(vec), f3.c(vec))
[1] TRUE
> microbenchmark(f0(vec), f1(vec), f2(vec), f3(vec), f3.c(vec))
Unit: microseconds
expr min lq median uq max neval
f0(vec) 15274.275 15347.870 15406.1430 15605.8470 19890.903 100
f1(vec) 15513.807 15575.229 15651.2970 17064.8830 18326.293 100
f2(vec) 21473.814 21558.989 21679.3210 22733.1710 27435.889 100
f3(vec) 51.715 56.050 75.4495 78.5295 100.730 100
f3.c(vec) 11.612 17.147 28.5570 31.3160 49.781 100
おそらくがあるいくつかの大手楽しい
library(compiler)
f3.c <- cmpfun(f3)
用との比較のため
f3 <- function(x) {
imin <- 1L
imax <- length(x)
while (imax >= imin) {
imid <- as.integer(imin + (imax - imin)/2)
if (x[imid] >= 0)
imax <- imid - 1L
else
imin <- imid + 1L
}
imax
}
:だから私はRでそれを書きました私がwrを持っているトリッキーなエッジケースong! Cへの移動、私は
> identical(f3(vec), f4(vec))
[1] TRUE
> microbenchmark(f3(vec), f3.c(vec), f4(vec))
Unit: nanoseconds
expr min lq median uq max neval
f3(vec) 52096 53192.0 54918.5 55539.0 69491 100
f3.c(vec) 10924 12233.5 12869.0 13410.0 20038 100
f4(vec) 553 796.0 893.5 1004.5 2908 100
findInterval
と
library(inline)
f4 <- cfunction(c(x = "numeric"), "
int imin = 0, imax = Rf_length(x) - 1, imid;
while (imax >= imin) {
imid = imin + (imax - imin)/2;
if (REAL(x)[imid] >= 0)
imax = imid - 1;
else
imin = imid + 1;
}
return ScalarInteger(imax + 1);
")
をした同様の質問がR-helpリストに頼まれた時に思いつきました。遅いが安全で、vec
が実際にソートされ、NA値を処理していることがチェックされます。 1は、(F3やF4を実装することを間違いなく悪くない)エッジで生きることを望んでいる場合(つまり、値のベクトルを調べ、その後
f5.i <- function(v)
.Internal(findInterval(v, 0 - .Machine$double.neg.eps, FALSE, FALSE))
は、ほぼ同じ速さCの実装などですが、おそらくより堅牢とベクトル化簡単な範囲のような計算のための第2引数で)。
+1うわー。私はこれからたくさんのことを学びます。そのような思慮深いとindepthの回答を投稿していただきありがとうございます –
あなたのf4関数を調達する際にエラーが発生しました。https://gist.github.com/anonymous/5785498 – Juancentro
@JuancentroコードのCバージョンでは、Cコンパイラが必要ですインストールされます。ウィンドウの場合、[以下の手順に従ってください](http://cran.r-project.org/bin/windows/Rtools/)。 –