Medie mobili
Le medie mobili (a volte chiamate moving averages) si usano nell’analisi delle serie temporali per attenuare il rumore. Il valore in ogni istante viene sostituito con la media dei valori nei punti temporali vicini (la finestra).
Un modo naturale per scrivere questa funzione è
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
}
Questa soluzione chiama mean() molte volte, il che è inefficiente. Un’alternativa è usare una variabile total così che, a ogni iterazione del ciclo, rimuovi l’elemento che non serve più e aggiungi quello nuovo.
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
}
In ogni caso, è molto più naturale scrivere codice con cicli rispetto a codice vettorializzato, ma questo può ridurre le prestazioni. Entrambe le versioni sopra sono inefficienti a modo loro. Prima di passare alla versione in C++ nel prossimo esercizio, scriviamo una versione che usi la vettorializzazione. rollmean1(), rollmean2() e un vettore casuale, x, sono disponibili nel tuo workspace. Ora completerai la definizione della funzione rollmean3() e confronterai le prestazioni di queste funzioni.
Questo esercizio fa parte del corso
Ottimizzare il codice R con Rcpp
Esercizio pratico interattivo
Prova a risolvere questo esercizio completando il codice di esempio.
# 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
)
}