直前の観測値で補完する(LOCF)
時系列に欠損がある場合、よく使われる手法のひとつが、欠損でない直近の値を前方に引き継ぐ方法です。これは last observation carried forward(直前の観測値の前方補完、LOCF)と呼ばれます。反復処理で自然に表現できます。以下は 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
)
*/