あなたの目的はただ一つのパスを作ることであるならば、それはあなたがC++での多くの経験を持っていない場合でも、Rcppに書くことは非常に簡単です:このような小さなについては
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::LogicalVector single_pass(Rcpp::CharacterVector x, Rcpp::String a, Rcpp::String b) {
R_xlen_t i = 0, n = x.size();
Rcpp::LogicalVector result(n);
for (; i < n; i++) {
result[i] = (x[i] == a || x[i] == b);
}
return result;
}
あなたの例で使用したものなど、オブジェクト、.Call
(おそらく)マスクRcppバージョンの速度のわずかなオーバーヘッド、
r_fun <- function(X) X == "A" | X == "B"
##
cpp_fun <- function(X) single_pass(X, "A", "B")
##
all.equal(r_fun(x), cpp_fun(x))
#[1] TRUE
microbenchmark::microbenchmark(
r_fun(x), cpp_fun(x), times = 1000L)
#Unit: microseconds
#expr min lq mean median uq max neval
#r_fun(x) 1.499 1.584 1.974156 1.6795 1.8535 37.903 1000
#cpp_fun(x) 1.860 2.334 3.042671 2.7450 3.1140 51.870 1000
しかし、より大きなベクトルの(私はこれをyであると仮定しています私たちの本当の意図)、それはかなり速いです:あなたはそれのための任意の使用を持っている場合
x2 <- sample(LETTERS, 10E5, replace = TRUE)
##
all.equal(r_fun(x2), cpp_fun(x2))
# [1] TRUE
microbenchmark::microbenchmark(
r_fun(x2), cpp_fun(x2), times = 200L)
#Unit: milliseconds
#expr min lq mean median uq max neval
#r_fun(x2) 78.044518 79.344465 83.741901 80.999538 86.368627 149.5106 200
#cpp_fun(x2) 7.104929 7.201296 7.797983 7.605039 8.184628 10.7250 200
ここで、上記の一般化でquick attemptです。
「x%in%c( "A"、 "B") ' – MrFlick
@MrFlick私はこれらの2つのオプションのタイミングを考えていましたが、実際にはほとんど違いは見られません。 – joran
@joranええ、私はあなたが大きなスピードアップを見せてくれるのではないでしょうか(そして、私はこれがどこにあるのか疑問に思うでしょう。パフォーマンスのボトルネックはありますが)それは単なる構文の代替です。 – MrFlick