gpt4 book ai didi

r - Rcpp 中的 na.locf 和 inverse.rle

转载 作者:行者123 更新时间:2023-12-04 11:01:27 26 4
gpt4 key购买 nike

我想检查 na.locf 是否有任何预先存在的技巧(来自 zoo 包),rleinverse.rleRCpp ?

我写了一个循环来实现,例如我做了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

关于r - Rcpp 中的 na.locf 和 inverse.rle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24004065/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com