Frage

Ich wollte überprüfen, ob es eine bereits bestehende trick für na.locf (aus zoo - Paket), rle und inverse.rle in RCpp?

Ich schrieb eine Schleife zu implementieren, z.B.Ich habe die Implementierung von na.locf(x, na.rm=FALSE, fromLast=FALSE) wie folgt:

#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;
}

Ich Frage mich nur, dass da diese sehr grundlegenden Funktionen, die jemand haben könnte, bereits umgesetzt in RCpp in einer besseren Art und Weise (kann vermeiden die Schleife), ODER einen schnelleren Weg?

War es hilfreich?

Lösung

Das einzige, was ich sagen würde ist, dass Sie Tests für NA zweimal für jeden Wert, wenn Sie brauchen nur zu tun es einmal.Prüfung für NA ist nicht eine Kostenlose operation.Vielleicht so etwas wie dieses:

//[[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;
}

Dies jedoch immer noch nicht unnötige Dinge, wie die Einstellung v jedes mal, wenn wir es nur tun, für die Letzte Zeit, die wir nicht sehen NA.Wir können versuchen, so etwas wie dieses:

//[[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;
}

Nun, wir können versuchen, einige benchmarks:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top