IniziaInizia gratis

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

Visualizza il corso

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
  )
}
Modifica ed esegui il codice