開始使用免費開始

移動平均(rolling means)

移動平均(有時也稱為 moving averages)常用於時間序列分析,用來平滑雜訊。每個時間點的數值會被其鄰近時間點(視窗,window)內數值的平均所取代。

撰寫此函式的一個直覺方式如下:

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
  )
}
編輯並執行程式碼