始める無料で始める

直前の観測値で補完する(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 コードを最適化する

コースを見る

演習の手順

  • currentNumericVectorNA 値で初期化します。
  • if 条件では、xi 番目の要素が NumericVectorNA かどうかを確認します。
  • 条件が真のときは、resi 番目の要素を current に設定します。
  • それ以外の場合は、currentxi 番目の要素に更新します。

実践的なインタラクティブ演習

このサンプルコードを完成させて、この演習に挑戦してみましょう。

#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
  )
*/
コードを編集して実行