1
votes

Donner l'ID de groupe pour les périodes de dates

J'essaye d'automatiser l'attribution d'un numéro de groupe par périodes de temps. Parce que j'écris une fonction pour agréger des séries chronologiques de données météorologiques par différentes périodes définies par l'utilisateur. Appelons "n" le nombre de sous-périodes

df2 =df %>% 
  group_by(date,id) %>%
  mutate(period = c(rep(seq(1,4-1, by = 1), each = as.integer(length(date)/4)),
                    rep(4, length(date)-((4-1)*as.integer(length(date)/4))))) 
df2

Je voudrais découper mes dates en un nombre "n" de périodes et ajouter le nombre de périodes à chaque ligne de mon bloc de données : Quelque chose comme ça si je veux des périodes de 4 jours:

df$period = c(rep(c(1:4), each = length(d1)/4), rep(c(1:4), each = length(d2)/4))
df

J'ai une longueur de date différente pour chaque identifiant dans mon ensemble de données réel. C'est pourquoi je veux construire les premiers groupes avec la même taille et le dernier avec le reste.

Imaginons que je veux des quatrièmes périodes: J'ai écrit ceci mais cela ne me renvoie que "4":

d1 = seq(as.Date("1910/1/1"), as.Date("1910/1/20"), "days")
d2 = seq(as.Date("1911/2/4"), as.Date("1911/2/27"), "days")
id1 = rep("1", length(d1))
id2 = rep("2", length(d2))       

df = data.frame(date = c(d1,d2), id = c(id1,id2))
df

Quelqu'un a une idée?

@hammoire:

Alors voici par exemple pour le premier ID j'ai 20 dates et si je veux le découper en 3 périodes: c (1,1,1,1,1,1, 2,2,2,2,2,2, 3,3,3,3,3,3,3,3)


4 commentaires

Pourriez-vous afficher une trame de données de la sortie souhaitée? Juste pour être sûr que je suis sur la bonne voie


Pouvez-vous m'expliquer comment le montrer ici?


Créez le vecteur d'entiers souhaité à la main, écrivez simplement à quoi vous voulez que la colonne finale "période" ressemble. c (1,1,1,2,2,2,3,3,3) par exemple. Puis collez-le dans la question.


Je voudrais avoir un numéro de période associé à chaque date, par exemple 1 si la date est dans la première "période" de date. Mais si je demande par exemple 4 périodes et que je n'ai pas un multiple de 4 pour le nombre de dates dans chaque groupe, je voudrais partager toutes les dates dans ces 4 périodes et la dernière sera constituée par tout le reste. Par exemple: 21 dates en 4 "périodes": 21/4 = 5,25 Donc les 3 premiers groupes de dates seront constitués de 5 dates et le dernier groupe des 6 restants


3 Réponses :


0
votes

en utilisant data.table: (pas très élégant mais fonctionne)

d[, N := .N, by=id]
d[, n := floor(N/4) ]
d[, j := mapply(function(N,n) seq(1, N, by=n) %>% list, N, n)]
d[, y := ifelse(t %in% unlist(j), 1, 0), by=id]
d[, y := cumsum(y), by=id]
d[, c("N","n","j") := NULL]
d

         date id  t y
 1: 1910-01-01  1  1 1
 2: 1910-01-02  1  2 1
 3: 1910-01-03  1  3 1
 4: 1910-01-04  1  4 1
 5: 1910-01-05  1  5 1
 6: 1910-01-06  1  6 2
 7: 1910-01-07  1  7 2
 8: 1910-01-08  1  8 2
 9: 1910-01-09  1  9 2
10: 1910-01-10  1 10 2
11: 1910-01-11  1 11 3
12: 1910-01-12  1 12 3
13: 1910-01-13  1 13 3
14: 1910-01-14  1 14 3
15: 1910-01-15  1 15 3
16: 1910-01-16  1 16 4
17: 1910-01-17  1 17 4
18: 1910-01-18  1 18 4
19: 1910-01-19  1 19 4
20: 1910-01-20  1 20 4
21: 1911-02-04  2  1 1
22: 1911-02-05  2  2 1
23: 1911-02-06  2  3 1
24: 1911-02-07  2  4 1
25: 1911-02-08  2  5 1
26: 1911-02-09  2  6 1
27: 1911-02-10  2  7 2
28: 1911-02-11  2  8 2
29: 1911-02-12  2  9 2
30: 1911-02-13  2 10 2
31: 1911-02-14  2 11 2
32: 1911-02-15  2 12 2
33: 1911-02-16  2 13 3
34: 1911-02-17  2 14 3
35: 1911-02-18  2 15 3
36: 1911-02-19  2 16 3
37: 1911-02-20  2 17 3
38: 1911-02-21  2 18 3
39: 1911-02-22  2 19 4
40: 1911-02-23  2 20 4
41: 1911-02-24  2 21 4
42: 1911-02-25  2 22 4
43: 1911-02-26  2 23 4
44: 1911-02-27  2 24 4
          date id  t y


3 commentaires

Merci mais ce n'est pas ce que je veux, car ici vous demandez 4 périodes mais vous en avez 5 à la fin pour la première pièce d'identité


ohh désolé, je pensais que tu avais besoin de périodes de 4, ou moins si c'est la dernière


maintenant ça devrait marcher, mais les réponses de Gregor sont bien meilleures!



2
votes

J'essaierais ceci:

df %>% 
   group_by(id) %>% 
   mutate(period = c(rep(1:n_period, each = n() %/% n_period), rep(n_period, n() %% n_period)))

Tous les extras seront attribués aux groupes dans l'ordre, donc si vous aviez 7 dates et 4 périodes, ce serait 1, 1 , 2, 2, 3, 3, 4

Alternativement, si vous voulez tous les extras dans le dernier groupe, par exemple, le cas de 4 périodes à 7 entrées est 1, 2, 3, 4, 4, 4, 4 , cela devrait fonctionner:

n_period = 4

df %>% 
  group_by(id) %>% 
  mutate(period = sort(rep_len(1:n_period, length.out = n())))
#          date id period
# 1  1910-01-01  1      1
# 2  1910-01-02  1      1
# 3  1910-01-03  1      1
# 4  1910-01-04  1      1
# 5  1910-01-05  1      1
# 6  1910-01-06  1      2
# 7  1910-01-07  1      2
# 8  1910-01-08  1      2
# 9  1910-01-09  1      2
# 10 1910-01-10  1      2
# 11 1910-01-11  1      3
# 12 1910-01-12  1      3
# 13 1910-01-13  1      3
# 14 1910-01-14  1      3
# 15 1910-01-15  1      3
# 16 1910-01-16  1      4
# 17 1910-01-17  1      4
# 18 1910-01-18  1      4
# 19 1910-01-19  1      4
# 20 1910-01-20  1      4
# ...
# 33 1911-02-16  2      3
# 34 1911-02-17  2      3
# 35 1911-02-18  2      3
# 36 1911-02-19  2      3
# 37 1911-02-20  2      3
# 38 1911-02-21  2      3
# 39 1911-02-22  2      4
# 40 1911-02-23  2      4
# 41 1911-02-24  2      4
# 42 1911-02-25  2      4
# 43 1911-02-26  2      4
# 44 1911-02-27  2      4


0 commentaires

-1
votes

Vous ne savez pas si c'est ce que vous recherchez? La fonction vous permet de spécifier le nombre de groupes, mais je ne suis pas sûr que vous souhaitiez définir automatiquement le nombre de groupes pour chaque id. Faites-moi savoir si c'est le cas et je peux essayer de modifier. Merci

#n specifies the number of desired groups

group_fun <- function(v, n) {
  len_v <- length(v)
  n_per_group <- floor(length(v)/n)
  output_temp <- sort(rep(1:n, times = n_per_group))
  output <- output_temp[1:len_v]
  output[is.na(output)] <- max(output_temp, na.rm = TRUE)
  output

}

group_fun(df$period[df$id==1], 3)

df %>% 
  group_by(id) %>%
  mutate(period =  group_fun(id, n = 3))


0 commentaires