向前填充最后一次观测值
在时间序列中遇到缺失数据时,一个常见做法是将最近一次非缺失的值向前填充。这被称为"最后一次观测值向前填充"(last observation carried forward)。这可以很自然地用迭代代码来表达。下面是一个 R 实现:
na_locf1 <- function(x) {
current <- NA
res <- x
for(i in seq_along(x)) {
if(is.na(x[i])) {
# Replace with current
res[i] <- current
} else {
# Set current
current <- x[i]
}
}
res
}
与滚动平均类似,想在保持可读性的同时将这段代码完全向量化非常困难。不过,由于这只是一个 for 循环,因此可以很容易地翻译成 C++。
工作区中已提供 na_locf1()。请将其改写为 C++ 并赋值给 na_locf2()。
本练习是课程的一部分
用 Rcpp 优化 R 代码
练习说明
- 将
current初始化为NumericVector的NA值。 if条件应检查x的第i个元素是否为NumericVector的NA。- 当条件为真时,将
res的第i个元素设置为current。 - 否则,将
current设置为x的第i个元素。
交互式实操练习
通过完成这段示例代码来试试这个练习。
#include
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector na_locf2(NumericVector x) {
// Initialize to NA
double current = ___::___();
int n = x.size();
NumericVector res = clone(x);
for(int i = 0; i < n; i++) {
// If ith value of x is NA
if(___::___(___)) {
// Set ith result as current
res[i] = ___;
} else {
// Set current as ith value of x
current = ___;
}
}
return res ;
}
/*** R
library(microbenchmark)
set.seed(42)
x <- rnorm(1e5)
# Sprinkle some NA into x
x[sample(1e5, 100)] <- NA
microbenchmark(
na_locf1(x),
na_locf2(x),
times = 5
)
*/