【问题标题】:Create ID for specific sequence of consecutive days based on grouping variable in R根据R中的分组变量为连续天的特定序列创建ID
【发布时间】:2019-08-06 21:48:04
【问题描述】:

对于国家/地区级别的事件列表,我们希望为特定国家/地区的连续几天创建一个唯一 ID(如果一个国家/地区连续两天或更长时间的事件 --> 创建唯一 ID),以便我最终可以将数据框简化为特定的事件序列,而不是事件日期。

我没有设法根据事件的顺序汇总数据。我相信这个响应是相似的 (Creating groups of consecutive days meeting a given criteria),但它是在 SQL 中。

数据格式如下:

country <- c("Angola","Angola","Angola","Angola","Angola", "Benin","Benin","Benin","Benin","Benin","Benin")
event_date <- as.Date(c("2017-06-16", "2017-06-17", "2017-06-18", "2017-08-22", "2017-08-23", "2019-04-18", "2019-04-19", "2019-04-20", "2018-03-15", "2018-03-16", "2016-03-17"))

mydata <- data.frame(country, event_date)

在输出中,我希望有一个新列,其 ID 对一个国家/地区的每个系列事件都是唯一的:

seq.ID &lt;- c(1,1,1,2,2,3,3,3,4,4,4)

mydata2 &lt;- data.frame(country, event_date, seq.ID)

所以最终,我可以将数据减少到国家和事件序列的级别:

mydata3 &lt;- mydata2[!duplicated(mydata2$seq.ID),]

【问题讨论】:

    标签: r lubridate


    【解决方案1】:

    试试:

    library(dplyr)
    
    mydata %>%
      group_by(country) %>%
      distinct(seq.ID = cumsum(event_date != lag(event_date, default = first(event_date)) + 1L)
    

    输出:

    # A tibble: 5 x 2
    # Groups:   country [2]
      seq.ID country
       <int> <fct>  
    1      1 Angola 
    2      2 Angola 
    3      1 Benin  
    4      2 Benin  
    5      3 Benin 
    

    您还可以在distinct 中使用.keep_all 参数并保留每个序列的第一个日期:

    mydata %>%
      group_by(country) %>%
      distinct(seq.ID = cumsum(event_date != lag(event_date, default = first(event_date)) + 1L),
               .keep_all = TRUE)
    
    # A tibble: 5 x 3
    # Groups:   country [2]
      country event_date seq.ID
      <fct>   <date>      <int>
    1 Angola  2017-06-16      1
    2 Angola  2017-08-22      2
    3 Benin   2019-04-18      1
    4 Benin   2018-03-15      2
    5 Benin   2016-03-17      3
    

    如果需要具有不同序列 ID 的非聚合输出,您可以这样做:

    mydata %>%
      mutate(
        seq.ID = cumsum(
          (event_date != lag(event_date, default = first(event_date)) + 1L) |
            country != lag(country, default = first(country))
        )
      )
    
       country event_date seq.ID
    1   Angola 2017-06-16      1
    2   Angola 2017-06-17      1
    3   Angola 2017-06-18      1
    4   Angola 2017-08-22      2
    5   Angola 2017-08-23      2
    6    Benin 2019-04-18      3
    7    Benin 2019-04-19      3
    8    Benin 2019-04-20      3
    9    Benin 2018-03-15      4
    10   Benin 2018-03-16      4
    11   Benin 2016-03-17      5
    

    请注意,您上一个 event_date 中有一个错字,这就是为什么输出与您想要的输出没有 100% 对应的原因。

    【讨论】:

    • 非常感谢......我刚刚意识到我错过了在代码中提供关键行(seq ID 应该是什么样子) - 并且只是对其进行了编辑。棘手的一点是,我希望每个独特的国家/地区序列都有自己的 ID(即它们不应该在不同国家/地区重复)。因此,最终我可以通过删除重复项轻松选择所有唯一的国家/地区序列。
    • 查看我的编辑 - 请注意,您的最后一个 event_date 中有错字,因此最后一行与您想要的输出不对应。
    • 非常感谢这个解决方案。虽然它适用于我提供的示例,但它不适用于具有完全相同数据结构的完整数据集。我仍在尝试找出问题所在,并在找到解决方案后通知您。
    • 刚刚发现我必须添加arrange(country, event_date) 才能使其与完整数据集正常工作。
    猜你喜欢
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    相关资源
    最近更新 更多