开始使用免费开始使用

滚动均值

滚动均值(有时也称移动平均)常用于时间序列分析以平滑噪声。每个时间点的值会被其相邻时间点(即"窗口")内数值的平均值所替代。

一种自然的写法是:

rollmean1 <- function(x, window = 3) {
  n <- length(x)
  res <- rep(NA, n)
  for(i in seq(window, n)) {
    res[i] <- mean(x[seq(i - window + 1, i)])
  }
  res
}

这会多次调用 mean(),效率不高。一个解决方案是使用 total 变量,在循环的每次迭代中移除不再需要的元素并加入新元素。

rollmean2 <- function(x, window = 3){
  n <- length(x)
  res <- rep(NA, n)
  total <- sum(head(x, window))
  res[window] <- total / window
  for(i in seq(window + 1, n)) {
    total <- total + x[i] - x[i - window]
    res[i] <- total / window
  }
  res
}

无论哪种方式,相较于向量化代码,写循环代码更自然,但这可能会降低性能。上面的两个版本各有低效之处。在下一练习编写 C++ 版本之前,先写一个使用向量化的版本。rollmean1()rollmean2() 以及一个随机向量 x 已在您的工作区中可用。现在请完成 rollmean3() 的函数定义,并对这些函数的性能进行基准测试。

本练习是课程的一部分

用 Rcpp 优化 R 代码

查看课程

交互式实操练习

通过完成这段示例代码来试试这个练习。

# Complete the definition of rollmean3()
rollmean3 <- function(x, window = 3) {
  # Add the first window elements of x
  initial_total <- ___(head(x, window))

  # The elements to add at each iteration    
  lasts <- tail(x, - window)
  
  # The elements to remove
  firsts <- head(x, - window)

  # Take the initial total and add the 
  # cumulative sum of lasts minus firsts
  other_totals <- ___ + ___(___ - firsts)

  # Build the output vector 
  c(
    rep(NA, window - 1), # leading NA
    initial_total / ___, # initial mean
    other_totals / ___   # other means
  )
}
编辑并运行代码