Medii mobile
Mediile mobile (cunoscute uneori și ca medii rulante) sunt folosite în analiza seriilor de timp pentru a elimina zgomotul. Valoarea din fiecare punct de timp este înlocuită cu media valorilor din punctele de timp din apropiere (fereastra).
O modalitate naturală de a scrie această funcție este
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
}
Aceast cod apelează mean() de foarte multe ori, ceea ce este ineficient. O soluție este să folosești o variabilă total, astfel încât la fiecare iterație a buclei să elimini elementul care nu mai este necesar și să adaugi cel nou.
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
}
În ambele cazuri, scrierea codului cu bucle este mult mai naturală decât cea vectorizată, însă poate reduce performanța. Ambele variante de mai sus sunt ineficiente în felul lor. Înainte de a trece la versiunea C++ din exercițiul următor, hai să scriem o versiune care folosește vectorizarea. rollmean1(), rollmean2() și un vector aleatoriu x sunt disponibile în spațiul tău de lucru. Vei completa definiția funcției rollmean3() și vei evalua performanța acestor funcții cu un microbenchmark.
Acest exercițiu face parte din cursul
Optimizarea codului R cu Rcpp
Exercițiu interactiv practic
Încearcă acest exercițiu completând acest cod de exemplu.
# 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
)
}