2015-12-29 12 views
6

Rで複数の論理比較を実行する最も速い方法は何ですか?Rで複数の論理比較を実行する最も速い方法は何ですか?

は、例えば、私はxの各エントリは、 "A" または "B"(とは何か)のいずれかであるかどうかをテストしたいベクトルx

set.seed(14) 
x = sample(LETTERS[1:4], size=10, replace=TRUE) 

を考えてみましょう。以下の作品

上記のコードは、ベクター全体の長さに3回ループします。 Rに1回だけループし、それが1つまたは別の条件を満たすかどうかを各項目についてテストする方法がありますか?

+3

「x%in%c( "A"、 "B") ' – MrFlick

+2

@MrFlick私はこれらの2つのオプションのタイミングを考えていましたが、実際にはほとんど違いは見られません。 – joran

+3

@joranええ、私はあなたが大きなスピードアップを見せてくれるのではないでしょうか(そして、私はこれがどこにあるのか疑問に思うでしょう。パフォーマンスのボトルネックはありますが)それは単なる構文の代替です。 – MrFlick

答えて

12

あなたの目的はただ一つのパスを作ることであるならば、それはあなたが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です。

関連する問題