Rata-rata bergulir
Rata-rata bergulir (kadang disebut moving averages) digunakan dalam analisis deret waktu untuk menghaluskan derau. Nilai pada setiap titik waktu diganti dengan rata-rata dari nilai pada titik-titik waktu di sekitarnya (disebut window).
Cara alami untuk menuliskan fungsi ini adalah
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
}
Kode di atas memanggil mean() berkali-kali, yang tidak efisien. Salah satu solusi adalah menggunakan variabel total sehingga pada setiap iterasi perulangan Anda menghapus elemen yang tidak lagi diperlukan dan menambahkan yang baru.
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
}
Bagaimanapun, menulis kode dengan perulangan biasanya lebih alami dibandingkan kode tervektorisasi, yang dapat menurunkan kinerja. Kedua versi di atas tidak efisien dengan caranya masing-masing. Sebelum membuat versi C++ pada latihan berikutnya, mari kita tulis versi yang menggunakan vektorisasi. rollmean1(), rollmean2(), dan sebuah vektor acak, x, tersedia di workspace Anda. Sekarang Anda akan melengkapi definisi fungsi rollmean3() dan membandingkan kinerja fungsi-fungsi ini.
Latihan ini adalah bagian dari kursus
Mengoptimalkan Kode R dengan Rcpp
Latihan interaktif praktis
Cobalah latihan ini dengan menyelesaikan kode contoh berikut.
# 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
)
}