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
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
)
}