Как сделать вектор в таблице данных, который суммирует диапазон значений на основе подмножеств в другом векторе? - PullRequest
0 голосов
/ 24 апреля 2018

То, что я пытаюсь сделать в R, - это добавить вектор в таблицу данных ниже, которая называется RecentActivity, которая выполняет вычисление суммированной суммы для Activity, включая только значения для Activity в сумме, где неделя не превышает 2 недели назад (по удостоверению личности).

Например: если определенный идентификатор измеряется на неделе 2, я хочу, чтобы RecentActivity суммировала все значения для этого идентификатора, где неделя равна 1 или 2. Если измерено на неделе 7, сумма должна содержать значения активности на неделе 6 и 7. В первую неделю должна быть включена только неделя 1.

Я бы хотел получить ответ в data.table из-за его скорости обработки.

Это данные, к которым я хочу добавить вектор RecentActivity:

x <- data.table(ID = c(1,1,1,2,2,2,3,4,4,4,4), 
                Week = c(1,2,7,1,20,21,1,1,2,5,6), 
                Activity = c(5,2,3,1,0,4,3,8,2,5,3))

Это желаемый результат:

x <- data.table(ID = c(1,1,1,2,2,2,3,4,4,4,4), 
                Week = c(1,2,7,1,20,21,1,1,2,5,6), 
                Activity = c(5,2,3,1,0,4,3,8,2,5,3), 
                RecentActivity = c(5,7,3,1,0,4,3,8,10,5,8))

В таблице идентификатор встречается несколько раз, поскольку его измеряли в разные недели. Недели можно пропустить, если ничего не измерено. Строка с Activity = 0 означает, что ID был измерен, но активность не найдена.

Мне кажется, я использую data.table:

x[, RecentActivity := sum(Activity[Week > (Week -2) & Week < (Week +1)]), by = c('ID')]

Однако это не приводит к желаемому результату.

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Альтернативный способ:

x[x[, .(ID, Week = Week + 1, Activity)],
  RecentActivity := Activity + i.Activity, on = c('ID','Week')]
x[is.na(RecentActivity), RecentActivity := Activity]
x

#     ID Week Activity RecentActivity
#  1:  1    1        5              5
#  2:  1    2        2              7
#  3:  1    7        3              3
#  4:  2    1        1              1
#  5:  2   20        0              0
#  6:  2   21        4              4
#  7:  3    1        3              3
#  8:  4    1        8              8
#  9:  4    2        2             10
# 10:  4    5        5              5
# 11:  4    6        3              8

Как предложил Фрэнк, мы также можем установить значение по умолчанию для RecentActivity, а затем добавить активность предыдущей недели:

x[, RecentActivity := Activity]
x[x[, .(ID, Week = Week + 1, Activity)],
  RecentActivity := RecentActivity + i.Activity, on = c('ID','Week')]
0 голосов
/ 24 апреля 2018

Вот решение, создающее новую группирующую переменную:

x <- data.table(ID = c(1,1,1,2,2,2,3,4,4,4,4), 
                Week = c(1,2,7,1,20,21,1,1,2,5,6), 
                Activity = c(5,2,3,1,0,4,3,8,2,5,3))
x[, group:=cumsum((Week-shift(Week))>2 | is.na(shift(Week))), ID]
x[, RecentActivity:=cumsum(Activity), by=.(ID, group)][]
# > x[, RecentActivity:=cumsum(Activity), by=.(ID, group)][]
#     ID Week Activity group RecentActivity
#  1:  1    1        5     1              5
#  2:  1    2        2     1              7
#  3:  1    7        3     2              3
#  4:  2    1        1     1              1
#  5:  2   20        0     2              0
#  6:  2   21        4     2              4
#  7:  3    1        3     1              3
#  8:  4    1        8     1              8
#  9:  4    2        2     1             10
# 10:  4    5        5     2              5
# 11:  4    6        3     2              8

Или за один шаг:

x[, RecentActivity:=cumsum(Activity), by=.(ID, cumsum((Week-shift(Week))>2 | is.na(shift(Week))))][]
...