ComenzarEmpieza gratis

Medias móviles

Las medias móviles (a veces llamadas promedios móviles) se usan en el análisis de series temporales para suavizar el ruido. El valor en cada instante se sustituye por la media de los valores en puntos cercanos (la ventana).

Una forma natural de escribir esta función es

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
}

Esto llama a mean() muchas veces, lo que es ineficiente. Una solución es usar una variable total para que, en cada iteración del bucle, elimines el elemento que ya no necesitas y añadas el nuevo.

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
}

Aun así, escribir código con bucles suele ser más natural que código vectorizado, lo que puede reducir el rendimiento. Ambas versiones anteriores son ineficientes a su manera. Antes de hacer la versión en C++ en el siguiente ejercicio, vamos a escribir una versión que use vectorización. rollmean1(), rollmean2() y un vector aleatorio, x, están disponibles en tu espacio de trabajo. Ahora completarás la definición de la función rollmean3() y compararás el rendimiento de estas funciones.

Este ejercicio forma parte del curso

Optimizar código de R con Rcpp

Ver curso

Ejercicio interactivo práctico

Prueba este ejercicio y completa el código de muestra.

# 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
  )
}
Editar y ejecutar código