開始使用免費開始

沿用最後一次觀測值

在時間序列中遇到遺漏值時,一個常見技巧是把最後一個非遺漏的值往後帶。這稱為「沿用最後一次觀測值」(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 初始化為 NumericVectorNA 值。
  • if 條件應檢查 x 的第 i 個元素是否為 NumericVectorNA
  • 若條件為真,將 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
  )
*/
編輯並執行程式碼