首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rcpp中的na.locf和inverse.rle

Rcpp中的na.locf和inverse.rle
EN

Stack Overflow用户
提问于 2014-06-02 22:05:51
回答 1查看 644关注 0票数 5

我想检查一下na.locf (来自zoo包)、rleinverse.rleRCpp中是否存在任何预先存在的技巧。

我编写了一个循环来实现,例如,我实现了na.locf(x, na.rm=FALSE, fromLast=FALSE),如下所示:

代码语言:javascript
复制
#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中以更好的方式(可能是避免循环)或更快的方式实现它们?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-02 23:37:53

我要说的唯一一件事是,当您只需要做一次时,您将对每个值进行两次NA测试。对NA的测试不是免费的操作。也许是这样的:

代码语言:javascript
复制
//[[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。我们可以试试这样的方法:

代码语言:javascript
复制
//[[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;
}

现在,我们可以尝试一些基准:

代码语言:javascript
复制
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
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24004065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档