CommencerCommencer gratuitement

Moyennes glissantes

Les moyennes glissantes (parfois appelées moyennes mobiles) sont utilisées en analyse de séries temporelles pour lisser le bruit. La valeur à chaque instant est remplacée par la moyenne des valeurs des instants proches (la fenêtre).

Une manière naturelle d’écrire cette fonction est

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
}

Cela appelle mean() de nombreuses fois, ce qui est inefficace. Une solution consiste à utiliser une variable total afin qu’à chaque itération de la boucle vous retiriez l’élément dont vous n’avez plus besoin et ajoutiez le nouveau.

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
}

Dans tous les cas, il est beaucoup plus naturel d’écrire du code avec des boucles que du code vectorisé, ce qui peut réduire les performances. Les deux versions ci‑dessus sont inefficaces à leur manière. Avant de passer à la version C++ dans l’exercice suivant, écrivons une version utilisant la vectorisation. rollmean1(), rollmean2() et un vecteur aléatoire, x, sont disponibles dans votre espace de travail. Vous allez maintenant compléter la définition de la fonction rollmean3() et comparer les performances de ces fonctions.

Cet exercice fait partie du cours

Optimiser du code R avec Rcpp

Afficher le cours

Exercice interactif pratique

Essayez cet exercice en complétant cet exemple de code.

# 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
  )
}
Modifier et exécuter le code