沿用最後一次觀測值
在時間序列中遇到遺漏值時,一個常見技巧是把最後一個非遺漏的值往後帶。這稱為「沿用最後一次觀測值」(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
)
*/