سؤال

كنت أرغب في التحقق مما إذا كان هناك أي خدعة موجودة مسبقا ل na.locf (من zoo حزمة), rle و inverse.rle في RCpp?

كتبت حلقة لتنفيذ ، على سبيل المثال.فعلت تنفيذ na.locf(x, na.rm=FALSE, fromLast=FALSE) على النحو التالي:

#include <Rcpp.h>
using namespace Rcpp;

//[[Rcpp::export]]
NumericVector naLocf(NumericVector x) {
  int n=x.size();
  for (int i=1;i<n;i++) {
    if (R_IsNA(x[i]) & !R_IsNA(x[i-1])) {
      x[i]=x[i-1];
    }
  }
  return x;
}

كنت أتساءل فقط أنه نظرا لأن هذه وظائف أساسية تماما، فقد يكون شخص ما قد نفذها بالفعل في RCpp بطريقة أفضل (قد يكون تجنب حلقة) أو بطريقة أسرع?

هل كانت مفيدة؟

المحلول

الشيء الوحيد الذي أود أن أقوله هو أن كنت اختبار ل NA مرتين لكل قيمة عندما تحتاج فقط إلى القيام بذلك مرة واحدة.اختبار ل NA ليست عملية حرة.ربما شيء من هذا القبيل:

//[[Rcpp::export]]
NumericVector naLocf(NumericVector x) {
    int n = x.size() ;
    double v = x[0]
    for( int i=1; i<n; i++){
        if( NumericVector::is_na(x[i]) ) {
            x[i] = v ;
        } else {
            v = x[i] ;    
        }
    }

    return x;
}

هذا لا يزال يفعل أشياء غير ضرورية ، مثل الإعداد v في كل مرة عندما يمكننا أن نفعل ذلك فقط للمرة الأخيرة ونحن لا نرى NA.يمكننا تجربة شيء من هذا القبيل:

//[[Rcpp::export]]
NumericVector naLocf3(NumericVector x) {
    double *p=x.begin(), *end = x.end() ;
    double v = *p ; p++ ;

    while( p < end ){
        while( p<end && !NumericVector::is_na(*p) ) p++ ;
        v = *(p-1) ;
        while( p<end && NumericVector::is_na(*p) ) {
            *p = v ;
            p++ ;
        }
    }

    return x;
}

الآن ، يمكننا تجربة بعض المعايير:

x <- rnorm(1e6)
x[sample(1:1e6, 1000)] <- NA 
require(microbenchmark)
microbenchmark( naLocf1(x), naLocf2(x), naLocf3(x) )
#  Unit: milliseconds
#       expr      min       lq   median       uq      max neval
# naLocf1(x) 6.296135 6.323142 6.339132 6.354798 6.749864   100
# naLocf2(x) 4.097829 4.123418 4.139589 4.151527 4.266292   100
# naLocf3(x) 3.467858 3.486582 3.507802 3.521673 3.569041   100
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top