R 中 group_by 的条件累积求和?

Conditional cumulative summing with group_by in R?

所以我有一个 ID 事件,我想使用 group_by(或一些类似的函数)来进行条件累积和。这是数据:

ID  Event
42  NA
42  1
42  2
42  NA
42  1
43  NA
43  1
43  2
43  2

我想要做的是有两个新的列来累计计算 1 和 2,而不折叠任何数据:

ID  Event   count_1s    count_2s
42  NA      0           0
42  1       1           0
42  2       1           1
42  NA      1           1
42  1       2           1
43  NA      0           0
43  1       1           0
43  2       1           1
43  2       1           2

所以我明白了如何使用 group_by 通过 ID 将它们全部汇总,如下所示:

t <- data %>% group_by(ID, Event) %>% summarize(count_1s = sum(!is.na(Event == 1)))

但我无法理解的是如何获得 运行 条件总和 - 似乎 group_by 会破坏我的数据,我需要维护每一行。

编辑:所以接受的答案非常有效,但还有一个问题。如果值因事件而异怎么办?例如:

ID  Event   count_a count_b
42  NA      0           0
42  1       1           0
42  2       1           1
42  NA      1           1
42  1       2           1
43  NA      0           0
43  3       1           0
43  4       1           1
43  4       1           2 

每个 ID 始终只有两个事件值(无论哪个是 a 哪个是 b),我希望它们每次都重置。

按 'ID' 列分组后,我们可以通过比较 'Event' 中等于 1 且不是 NA 的元素来创建 'count_1s',然后 cumsum 逻辑索引。以类似的方式,我们可以创建 'count_2s'.

 library(dplyr)
 data %>% 
    group_by(ID) %>%
    mutate(count_1s= cumsum(Event==1 & !is.na(Event)),
           count_2s= cumsum(Event==2 & !is.na(Event)))
#     ID Event count_1s count_2s
#  (int) (int)    (int)    (int)
#1    42    NA        0        0
#2    42     1        1        0
#3    42     2        1        1
#4    42    NA        1        1
#5    42     1        2        1
#6    43    NA        0        0
#7    43     1        1        0
#8    43     2        1        1
#9    43     2        1        2

更新

使用 OP 的更新数据集,在我们按 'ID' 分组后,我们可以创建一个新列 'Event1',方法是将 'Event' 转换为 factor class,然后将其强制返回 numeric class(或者另一种选择是 match 使用 'Event' 的 unique 元素 'Event',然后像以前一样创建 'count_a' 和 'count_b'。

data2 %>%
   group_by(ID) %>% 
   mutate(Event1= as.numeric(factor(Event, levels=unique(Event))), 
          count_a= cumsum(Event1==1 & !is.na(Event1)), 
          count_b= cumsum(Event1==2 & !is.na(Event1))) %>%
   select(-Event1)
#    ID Event count_a count_b
#  (int) (int)   (int)   (int)
#1    42    NA       0       0
#2    42     1       1       0
#3    42     2       1       1
#4    42    NA       1       1
#5    42     1       2       1
#6    43    NA       0       0
#7    43     3       1       0
#8    43     4       1       1
#9    43     4       1       2

数据

data <- structure(list(ID = c(42L, 42L, 42L, 42L, 42L, 43L, 43L, 43L, 
43L), Event = c(NA, 1L, 2L, NA, 1L, NA, 1L, 2L, 2L)), .Names = c("ID", 
"Event"), class = "data.frame", row.names = c(NA, -9L))

data2 <- structure(list(ID = c(42L, 42L, 42L, 42L, 42L, 43L, 43L, 43L, 
43L), Event = c(NA, 1L, 2L, NA, 1L, NA, 3L, 4L, 4L)), .Names = c("ID", 
"Event"), row.names = c(NA, -9L), class = "data.frame")