【问题标题】:Conditional cumulative summing with group_by in R?R中的group_by条件累积求和?
【发布时间】:2015-09-08 13:11:33
【问题描述】:

所以我有一个事件的 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 无关紧要),我希望它们每次都重置。

【问题讨论】:

    标签: r conditional cumulative-sum


    【解决方案1】:

    按“ID”列分组后,我们可以通过比较“Event”中等于1且不是NA的元素,然后比较cumsum逻辑索引来创建“count_1s”。以类似的方式,我们可以创建“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 类,然后将其强制转换回numeric 类(或另一种选择是matching '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")
    

    【讨论】:

    • 谢谢@akrun -- 我更新了这个问题,知道如何计算这个问题吗?
    • @skathan count_acount_b 是什么?
    • 所以基本上,我想做和以前完全相同的事情,但我不能说“Event==1”和“Event==2”,因为每个ID都会改变数字。所以 ID 42 会有事件 1 和 2,ID 43 可能有事件 6 和 7,ID 8 可能有事件 14 和 37。每个 ID 只有 2 个事件出现一定次数,但它们每次都是两个不同的值.
    • 您可以为此转换为factor
    • 如何转换成因子?
    猜你喜欢
    • 2013-05-20
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    相关资源
    最近更新 更多