Klouzavé průměry
Klouzavé průměry (někdy zvané pohyblivé průměry) se v analýze časových řad používají k vyhlazení šumu. Hodnota v každém časovém bodě se nahradí průměrem hodnot v okolních bodech (okno).
Přirozený způsob, jak tuto funkci zapsat, je:
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
}
Tato funkce volá mean() mnohokrát, což je neefektivní. Jedno z řešení je použít proměnnou total, takže v každé iteraci smyčky odečteš prvek, který už nepotřebuješ, a přičteš nový.
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
}
V každém případě je zápis smyčkového kódu přirozenější než vektorizovaný přístup, což může snižovat výkon. Obě verze výše jsou každá svým způsobem neefektivní. Než napíšeš C++ verzi v příštím cvičení, zkusme napsat variantu využívající vektorizaci. V pracovním prostředí máš k dispozici funkce rollmean1(), rollmean2() a náhodný vektor x. Teď dokončíš definici funkce rollmean3() a porovnáš výkon všech tří funkcí.
Toto cvičení je součástí kurzu
Optimizing R Code with Rcpp
Interaktivní cvičení na vyzkoušení si v praxi
Vyzkoušejte si toto cvičení dokončením tohoto ukázkového kódu.
# 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
)
}