Укажите идентификатор группы для периодов дат - PullRequest
1 голос
/ 09 апреля 2020

Я пытаюсь автоматизировать присвоение номера группы по периодам времени. Потому что я пишу функцию для агрегирования временных рядов данных о погоде по различным периодам времени, определенным пользователем. Давайте назовем «n» числом подпериодов

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

Я хотел бы разделить мои даты на число «n» периодов и добавить номер периода в каждую строку моего фрейма данных: что-то вот так, если я хочу периоды в 4 дня:

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

У меня разные даты для каждого идентификатора в моем наборе реальных данных. Вот почему я хочу создать первые группы с одинаковым размером и последнюю с остальными.

Давайте представим, что мне нужны четвертые периоды: я написал это, но это возвращает мне только «4»:

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

У кого-нибудь есть идея?

@ hammoire:

Итак, для примера для первого идентификатора у меня есть 20 дат, и если я хочу разрезать его на 3 периода: c (1,1,1,1, 1,1,2,2,2,2,2,2,3,3,3,3,3,3,3)

Спасибо

Ответы [ 3 ]

2 голосов
/ 09 апреля 2020

Я бы попробовал это:

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

Любые дополнительные функции будут назначаться группам по порядку, поэтому, если бы у вас было 7 дат и 4 периода, это было бы 1, 1, 2, 2, 3, 3, 4

В качестве альтернативы, если вы хотите, чтобы все дополнительные элементы в последней группе, например, 4-периодный 7-элементный регистр, был 1, 2, 3, 4, 4, 4, 4, это должно работать:

df %>% 
   group_by(id) %>% 
   mutate(period = c(rep(1:n_period, each = n() %/% n_period), rep(n_period, n() %% n_period)))
0 голосов
/ 09 апреля 2020

Не уверен, что это то, что вы ищете? Функция позволяет вам указать количество групп, но я не уверен, хотите ли вы автоматически определить количество групп для каждого идентификатора. Дайте мне знать, если это так, и я могу попробовать и изменить. Спасибо

#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 голосов
/ 09 апреля 2020

с использованием data.table: (не очень элегантно, но работает)

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...