Поднабор данных, основанный на последовательной разнице дат - PullRequest
0 голосов
/ 22 марта 2020

Преамбула: Основная проблема заключается в том, как установить поднабор данных на основе идентификаторов, формируя поднаборы внутри идентификатора на основе последовательных временных разниц. Подсказка по этому вопросу была бы очень кстати.

Полный вопрос / настройка: У меня есть набор данных dt в формате data.table, который выглядит как

  date       id val1 val2
  %d.%m.%Y
1 01.01.2000  1   5    10
2 09.01.2000  1   4     9
3 01.08.2000  1   3     8
4 01.01.2000  2   2     7
5 01.01.2000  3   1     6
6 14.01.2000  3   7     5
7 28.01.2000  3   8     4
8 01.06.2000  3   9     3

Я хочу объединить наблюдения (сгруппированные по id), которые находятся на расстоянии не более двух недель (последовательно от наблюдения до наблюдения). Под объединением я подразумеваю, что для каждого подмножества I

  • сохранит значение последнего наблюдения val1
  • , заменив val2 последнего наблюдения на сумму всех значений из val2 группы
  • добавьте counter, сколько наблюдений собралось в этой группе.

Т.е. я хочу получить такой набор данных, как этот

  date       id val1 val2 counter
  %d.%m.%Y
2 09.01.2000  1   4    19       2
3 01.08.2000  1   3     8       1
4 01.01.2000  2   2     7       1
7 28.01.2000  3   8    15       3
8 01.06.2000  3   9     3       1

Тем не менее, я пытаюсь обернуть голову вокруг функций data.table, в частности .SD, и хочу решить проблему с помощью этих инструментов.

Пока я знаю

  • что я могу указать, что я имею в виду под первым и последним, используя setkey(dt,date)
  • , что я могу заменить последние val2 подмножества на сумму dt[, val2 := replace(val2, .N, sum(val2[-.N], na.rm = TRUE)), by=id]
  • , что Я получаю длину подмножества с помощью [.N]
  • как удалить строки
  • , чтобы вычислить разницу между двумя датами с помощью difftime(strptime(dt$date[1],format ="%d.%m.%Y"),strptime(dt$date[2],format ="%d.%m.%Y"),units="weeks")

Однако Я не могу понять, как поднастроить наблюдения так, чтобы каждое подмножество содержало только группы наблюдений того же id с датами (последовательных) расстояний максимум 2 недели.

Любая помощь приветствуется. Большое спасибо заранее.

1 Ответ

0 голосов
/ 22 марта 2020

Хитрость заключается в использовании cumsum() для условия. В этом случае состояние более 14 дней. Когда условие истинно, накопленная сумма увеличивается.

df %>%
  mutate(rownumber = row_number()) %>%
  group_by(id) %>%
  mutate(interval = as.numeric(as.Date(date, format = "%d.%m.%Y") - as.Date(lag(date), format = "%d.%m.%Y"))) %>%
  mutate(interval = ifelse(is.na(interval), 0, interval)) %>%
  mutate(group = cumsum(interval > 14) + 1) %>%
  ungroup() %>%
  group_by(id, group) %>%
  summarise(
    rownumber = last(rownumber),
    date = last(date),
    val1 = last(val1),
    val2 = sum(val2),
    counter = n()
  ) %>%
  select(rownumber, date, id, val1, val2, counter)

Выход

  rownumber date          id  val1  val2 counter
      <int> <chr>      <int> <int> <int>   <int>
1         2 09.01.2000     1     4    19       2
2         3 01.08.2000     1     3     8       1
3         4 01.01.2000     2     2     7       1
4         7 28.01.2000     3     8    15       3
5         8 01.06.2000     3     9     3       1
...