2015-12-29 7 views
6

आर में कई लॉजिकल तुलना करने का सबसे तेज़ तरीका क्या है?आर में कई लॉजिकल तुलना करने का सबसे तेज़ तरीका क्या है?

वेक्टर x

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

मैं अगर x की प्रत्येक प्रविष्टि या तो एक 'ए' या 'बी' है परीक्षण करना चाहते हैं (और नहीं कुछ और) उदाहरण के लिए विचार करें। निम्नलिखित काम

x == "A" | x == "B" 
[1] TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE 

उपरोक्त कोड पूरे वेक्टर की लंबाई के माध्यम से तीन गुना लूप करता है। क्या आरओ लूप में केवल एक बार एक तरीका है और प्रत्येक आइटम के लिए परीक्षण करें कि क्या यह एक या दूसरी स्थिति को संतुष्ट करता है?

+3

कैसे: 'x% में% c (" ए "," बी ")' – MrFlick

+2

@MrFlick मैं उन दो विकल्पों के समय के साथ टकरा रहा हूं और मुझे वास्तव में कोई अंतर नहीं दिख रहा है। और जब मैं इसे बड़ा कर देता हूं तब भी स्केल नैनोसेकंड पर होता है, इसलिए मैं थोड़ा खो देता हूं। – joran

+3

@ जोरन हाँ, मुझे छवि नहीं है कि आप एक बड़ी गति में वृद्धि देखेंगे (और मुझे इस बात पर संदेह होगा कि यह कोई है प्रदर्शन बाधा है) लेकिन यह सिर्फ एक वाक्यविन्यास विकल्प है। – MrFlick

उत्तर

12

अपने उद्देश्य सिर्फ एक पास बनाने के लिए है, तो उस 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 है आप इसके लिए किसी भी उपयोग किया है।

संबंधित मुद्दे

 संबंधित मुद्दे