J'essaie d'utiliser dplyr dans R pour calculer des statistiques glissantes (moyenne, sd, etc) à partir d'une fenêtre dynamique basée sur des dates et pour des modèles spécifiques. Par exemple, au sein de groupes d'éléments, je voudrais calculer la moyenne mobile pour toutes les données 10 jours auparavant. Les dates des données ne sont pas séquentielles et ne sont pas complètes, je ne peux donc pas utiliser une fenêtre fixe.
Une façon de le faire est d'utiliser rollapply en faisant référence à la largeur de la fenêtre comme indiqué ci-dessous. Cependant, j'ai du mal à calculer la largeur dynamique. Je préférerais une méthode qui omette l'étape intermédiaire de calcul de la fenêtre et qui calcule simplement sur la base de la date_lookback. Voici un petit exemple.
J'ai utilisé des boucles for pour faire cela, mais elles sont très lentes.
library(dplyr)
library(zoo)
date_lookback <- 10 #days to look back for rolling calcs
df <- data.frame(label = c(rep("a",5),rep("b",5)),
date = as.Date(c("2017-01-02","2017-01-20",
"2017-01-21","2017-01-30","2017-01-31","2017-01-05",
"2017-01-08","2017-01-09","2017-01-10","2017-01-11")),
data = c(790,493,718,483,825,186,599,408,108,666),stringsAsFactors = FALSE) %>%
mutate(.,
cut_date = date - date_lookback, #calcs based on sample since this date
dyn_win = c(1,1,2,3,3,1,2,3,4,5), ##!! need to calculate this vector??
roll_mean = rollapply(data, align = "right", width = dyn_win, mean),
roll_sd = rollapply(data, align = "right", width = dyn_win, sd))
Ce sont les résultats roll_mean et roll_sd que je recherche :
> df
label date data cut_date dyn_win roll_mean roll_sd
1 a 2017-01-02 790 2016-12-23 1 790.0000 NA
2 a 2017-01-20 493 2017-01-10 1 493.0000 NA
3 a 2017-01-21 718 2017-01-11 2 605.5000 159.0990
4 a 2017-01-30 483 2017-01-20 3 564.6667 132.8847
5 a 2017-01-31 825 2017-01-21 3 675.3333 174.9467
6 b 2017-01-05 186 2016-12-26 1 186.0000 NA
7 b 2017-01-08 599 2016-12-29 2 392.5000 292.0351
8 b 2017-01-09 408 2016-12-30 3 397.6667 206.6938
9 b 2017-01-10 108 2016-12-31 4 325.2500 222.3921
10 b 2017-01-11 666 2017-01-01 5 393.4000 245.5928
Merci d'avance.