在他的"高级R" Hadley Wickham说," noNA(x)
声称向量x
不包含任何缺失值。"但是我仍然不知道如何使用它。我无法做到
if (noNA(x))
do this
那我该如何使用呢?
答案 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
版本确实更快。