Étant donné un data.frame qui contient une série temporelle et un ou plusieurs champs de regroupement. Nous avons donc plusieurs séries chronologiques - une pour chaque combinaison de regroupement. Mais certaines dates sont manquantes. Alors, quel est le plus simple (en termes de "moyen le plus tidy") d'ajouter ces dates aux bonnes valeurs de regroupement?Remplir des dates manquantes dans une série chronologique groupée - une voie inverse?
Normalement, je dirais que je génère un data.frame avec toutes les dates et que je fais un full_join avec mes séries temporelles. Mais maintenant, nous devons le faire pour chaque combinaison de valeurs de regroupement - et remplir les valeurs de regroupement.
Regardons un exemple:
D'abord, je créer un data.frame avec des valeurs manquantes:
library(dplyr)
library(lubridate)
set.seed(1234)
# Time series should run vom 2017-01-01 til 2017-01-10
date <- data.frame(date = seq.Date(from=ymd("2017-01-01"), to=ymd("2017-01-10"), by="days"), v = 1)
# Two grouping dimensions
d1 <- data.frame(d1 = c("A", "B", "C", "D"), v = 1)
d2 <- data.frame(d2 = c(1, 2, 3, 4, 5), v = 1)
# Generate the data.frame
df <- full_join(date, full_join(d1, d2)) %>%
select(date, d1, d2)
# and ad to value columns
df$v1 <- runif(200)
df$v2 <- runif(200)
# group by the dimension columns
df <- df %>%
group_by(d1, d2)
# create missing dates
df.missing <- df %>%
filter(v1 <= 0.8)
# So now 2017-01-01 and 2017-01-10, A, 5 are missing now
df.missing %>%
filter(d1 == "A" & d2 == 5)
# A tibble: 8 x 5
# Groups: d1, d2 [1]
date d1 d2 v1 v2
<date> <fctr> <dbl> <dbl> <dbl>
1 2017-01-02 A 5 0.21879954 0.1335497
2 2017-01-03 A 5 0.32977018 0.9802127
3 2017-01-04 A 5 0.23902573 0.1206089
4 2017-01-05 A 5 0.19617465 0.7378315
5 2017-01-06 A 5 0.13373890 0.9493668
6 2017-01-07 A 5 0.48613541 0.3392834
7 2017-01-08 A 5 0.35698708 0.3696965
8 2017-01-09 A 5 0.08498474 0.8354756
Donc, pour ajouter les dates manquantes je générons une data.frame avec toutes les dates:
start <- min(df.missing$date)
end <- max(df.missing$date)
all.dates <- data.frame(date=seq.Date(start, end, by="day"))
Non Je veux faire quelque chose comme (rappelez-vous: df.missing est group_by (d1, d2))
df.missing %>%
do(my_join())
Alors nous allons définir my_join():
my_join <- function(data) {
# get value of both dimensions
d1.set <- data$d1[[1]]
d2.set <- data$d2[[1]]
tmp <- full_join(data, all.dates) %>%
# First we need to ungroup. Otherwise we can't change d1 and d2 because they are grouping variables
ungroup() %>%
mutate(
d1 = d1.set,
d2 = d2.set
) %>%
group_by(d1, d2)
return(tmp)
}
Maintenant, nous pouvons appeler my_join() pour chaque combinaison et un coup d'oeil à "A/5"
df.missing %>%
do(my_join(.)) %>%
filter(d1 == "A" & d2 == 5)
# A tibble: 10 x 5
# Groups: d1, d2 [1]
date d1 d2 v1 v2
<date> <fctr> <dbl> <dbl> <dbl>
1 2017-01-02 A 5 0.21879954 0.1335497
2 2017-01-03 A 5 0.32977018 0.9802127
3 2017-01-04 A 5 0.23902573 0.1206089
4 2017-01-05 A 5 0.19617465 0.7378315
5 2017-01-06 A 5 0.13373890 0.9493668
6 2017-01-07 A 5 0.48613541 0.3392834
7 2017-01-08 A 5 0.35698708 0.3696965
8 2017-01-09 A 5 0.08498474 0.8354756
9 2017-01-01 A 5 NA NA
10 2017-01-10 A 5 NA NA
Great! C'est ce que nous cherchions. Mais nous devons définir d1 et d2 dans my_join et il se sent un peu maladroit.
Donc, y a-t-il une voie inverse de cette solution?
PS: J'ai mis le code dans un point essentiel: https://gist.github.com/JerryWho/1bf919ef73792569eb38f6462c6d7a8e
JerryWho que vous avez reçu quelques bonnes réponses ci-dessous. Si quelqu'un vous a aidé, envisagez de l'accepter comme une réponse (coche à gauche). Il permet à la communauté de connaître la réponse qui a fonctionné pour votre cas. Vous pouvez changer votre réponse acceptée dans le futur si vous le souhaitez. – CPak