如何在Rcpp中使用noNA?

时间:2017-01-26 12:04:57

标签: r rcpp

在他的"高级R" Hadley Wickham说," noNA(x)声称向量x不包含任何缺失值。"但是我仍然不知道如何使用它。我无法做到

if (noNA(x))
    do this

那我该如何使用呢?

http://adv-r.had.co.nz/Rcpp.html#rcpp-sugar

1 个答案:

答案 0 :(得分:4)

许多Rcpp糖表达式是通过模板类实现的,这些模板类对于输入对象已知没有缺失值的情况具有特殊性,从而允许底层算法避免必须执行处理NA值的额外工作(例如调用is_na)。这是唯一可能的,因为VectorBase类有一个布尔参数,指示底层对象是否可以(可以,而不是 ){{1}值或不。

noNA返回(在NA对象上调用时)Nona模板类的实例。请注意,VectorBase本身来自

Nona

意味着返回的对象使用基本上表示&#34的信息进行编码;您可以假设此数据没有Rcpp::VectorBase<RTYPE, false, Nona<RTYPE,NA,VECTOR>> // ^^^^^ 值&#34;。

例如,NA是通过Rcpp::sum命名空间中的Sum类实现的。在default case中,我们看到有额外的工作来管理缺失值的可能性:

Rcpp::sugar

另一方面,对于输入没有缺失值的情况,还有a specialization,其中算法的工作量较少:

STORAGE get() const {
    STORAGE result = 0 ;
    R_xlen_t n = object.size() ;
    STORAGE current ;
    for( R_xlen_t i=0; i<n; i++){
        current = object[i] ;
        if( Rcpp::traits::is_na<RTYPE>(current) )   // here
            return Rcpp::traits::get_na<RTYPE>() ;  // here
        result += current ;
    }
    return result ;
}

要回答你的问题&#34;我如何在实践中应用这个?&#34;,这是一个例子:

STORAGE get() const {
    STORAGE result = 0 ;
    R_xlen_t n = object.size() ;
    for( R_xlen_t i=0; i<n; i++){
        result += object[i] ;
    }
    return result ;
}

对这两个功能进行基准测试,

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
int Sum(IntegerVector x) {
    return sum(x);
}

// [[Rcpp::export]]
int SumNoNA(IntegerVector x) {
    return sum(noNA(x));
}

set.seed(123) x <- as.integer(rpois(1e6, 25)) all.equal(Sum(x), SumNoNA(x)) # [1] TRUE microbenchmark::microbenchmark( Sum(x), SumNoNA(x), times = 500L ) # Unit: microseconds # expr min lq mean median uq max neval # Sum(x) 577.386 664.620 701.2422 677.1640 731.7090 1214.447 500 # SumNoNA(x) 454.990 517.709 556.5783 535.1935 582.7065 1138.426 500 版本确实更快。