Сводка последних значений N - PullRequest
0 голосов
/ 17 января 2019

Я пытаюсь получить сводную статистику (здесь сумма и максимум) с большинством последних N значений.

Исходные данные:

dt = data.table(id = c('a','a','a','a','b','b','b','b'),
                week = c(1,2,3,4,1,2,3,4),
                value = c(2, 3, 1, 0, 5, 7,3,2))

Желаемый результат:

dt = data.table(id = c('a','a','a','a','b','b','b','b'),
                    week = c(1,2,3,4,1,2,3,4),
                    value = c(2, 3, 1, 0, 5, 7,3,2),
                    sum_recent2week = c(NA, NA, 5, 4, NA, NA, 12, 10),
                    max_recent2week = c(NA, NA, 3, 3, NA, NA, 7, 7))

С данными, я хотел бы иметь сумму и максимум 2 (N = 2) самых последних значений для каждой строки по идентификатору. 4-й (sum_recent2week) и 5-й (max_recent2week) столбцы - мои нужные столбцы

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Я уверен, что это можно сделать гораздо более элегантно, но есть одна tidyverse возможность:

dt %>%
 group_by(id) %>%
 mutate(sum_recent2week = lag(value + lead(value), n = 2),
        max_recent2week = pmax(lag(value, n = 2), lag(value, n = 1))) %>%
 rowid_to_column() %>%
 select(-week, -value) %>%
 top_n(-2) %>%
 right_join(dt %>%
            rowid_to_column(), by = c("rowid" = "rowid",
                                      "id" = "id")) %>%
 select(-rowid)

  id    sum_recent2week max_recent2week  week value
  <chr>           <dbl>           <dbl> <dbl> <dbl>
1 a                 NA              NA     1.    2.
2 a                 NA              NA     2.    3.
3 a                  5.              3.    3.    1.
4 a                  4.              3.    4.    0.
5 b                 NA              NA     1.    5.
6 b                 NA              NA     2.    7.
7 b                 12.              7.    3.    3.
8 b                 10.              7.    4.    2.

Во-первых, он вычисляет "sum_recent2week" и "max_recent2week" для группы. Во-вторых, он выбирает последние две строки в группе. Наконец, он сливается с исходными данными.

Или, если вы хотите вычислить его для всех строк, а не только для последних двух строк в группе:

dt %>%
 group_by(id) %>%
 mutate(sum_recent2week = lag(value + lead(value), n = 2),
        max_recent2week = pmax(lag(value, n = 2), lag(value, n = 1)))
0 голосов
/ 18 января 2019

Вы можете использовать rollsum и rollmax из пакета zoo.

dt[, `:=`(sum_recent2week = 
            shift(rollsum(value, 2, align = 'left', fill = NA), 2),
          max_recent2week = 
            shift(rollmax(value, 2, align = 'left', fill = NA), 2))
   , id]

Для суммы, если вы используете версию таблицы данных> = 1.12, вы можете использовать data.table::frollmean. Значение по умолчанию для frollmean равно fill = NA, поэтому нет необходимости указывать это в этом случае.

dt[, `:=`(sum_recent2week = 
            shift(frollmean(value, 2, align = 'left')*2, 2),
          max_recent2week = 
            shift(rollmax(value, 2, align = 'left', fill = NA), 2))
   , id]
...