开始使用免费开始使用

向前填充最后一次观测值

在时间序列中遇到缺失数据时,一个常见做法是将最近一次非缺失的值向前填充。这被称为"最后一次观测值向前填充"(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
  )
*/
编辑并运行代码