【问题标题】:Create date range based on sparse variable by group in R在R中按组创建基于稀疏变量的日期范围
【发布时间】:2020-10-10 16:14:26
【问题描述】:

我有稀疏的数据,其中有一个定期间隔的分数,以及多个主题的更定期间隔的测量以及相应的日期。我想根据每个主题 ID 的分数日期生成日期范围,即。从评分日期开始,到下一个评分日期结束(如果分数不在这些日期,则从第一个/最后一个受试者观察开始/结束)。

然后,我想对这些日期范围内的测量变量进行平均。平均步骤应该很简单,但我坚持生成日期范围。

以下是数据样本和我如何设想结果数据的示例

样本数据:

structure(list(ID = c("A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", 
"B", "B", "C", "C", "C", "D", "D", "D", "D", "D", "D", "D", "D", 
"D", "D", "D", "D", "D", "D", "D"), date = c("1/21/2020", "1/27/2020", 
"2/1/2020", "2/3/2020", "2/5/2020", "2/6/2020", "2/8/2020", "2/9/2020", 
"2/11/2020", "2/12/2020", "2/13/2020", "2/15/2020", "2/18/2020", 
"2/20/2020", "2/21/2020", "2/22/2020", "2/25/2020", "2/1/2020", 
"2/5/2020", "2/7/2020", "2/8/2020", "2/11/2020", "2/12/2020", 
"1/30/2020", "2/10/2020", "2/11/2020", "2/6/2020", "2/7/2020", 
"2/8/2020", "2/9/2020", "2/11/2020", "2/13/2020", "2/14/2020", 
"2/16/2020", "2/17/2020", "2/20/2020", "2/23/2020", "2/26/2020", 
"3/1/2020", "3/3/2020", "3/5/2020"), score = c(0.5, 2, NA, NA, 
3, NA, NA, NA, NA, NA, 2.5, NA, NA, 1.5, NA, NA, NA, 3, NA, NA, 
2.5, NA, 1, 0.5, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 14, 
NA, NA, 11.5, NA, 9.5, NA), measure = c(0.394160734, 0.722462998, 
0.82984815, 0.738432745, 0.321792398, 0.167492308, 0.218020898, 
0.929210786, 0.686818585, 0.939678073, 0.708172942, 0.299863884, 
0.48216267, 0.290307369, 0.801947902, 0.579418467, 0.78101844, 
0.219494852, 0.875129822, 0.517971003, 0.475625007, 0.723003744, 
0.257473477, 0.629818537, 0.817369151, 0.628573413, 0.364660834, 
0.5971024, 0.002274261, 0.318937617, 0.983917106, 0.685933928, 
0.487922831, 0.151769304, 0.392413694, 0.012429414, 0.149627658, 
0.011724992, 0.536998203, 0.798399999, 0.763353822)), class = "data.frame", row.names = c(NA, 
-41L))

答案数据:

structure(list(ID = c("A", "A", "A"), startDate = c("1/21/2020", 
"1/27/2020", "2/5/2020"), endDate = c("1/27/2020", "2/5/2020", 
"2/13/2020"), score = c(0.5, 2, 3), measure = c(0.394160734, 
0.763581298, 0.543835508)), class = "data.frame", row.names = c(NA, 
-3L))

【问题讨论】:

    标签: r date dplyr time-series tidyverse


    【解决方案1】:

    这是dplyr 的一种方式:

    library(dplyr)
    
    df %>%
      group_by(ID, grp = cumsum(!is.na(score))) %>%
      summarise(start_date = first(date),
                score = first(score),
                measure = mean(measure)) %>%
      mutate(end_date = lead(start_date, default = last(start_date))) %>%
      select(-grp)
    
    #       ID    start_date score measure end_date 
    #   <chr> <chr>      <dbl>   <dbl> <chr>    
    # 1 A     1/21/2020    0.5   0.394 1/27/2020
    # 2 A     1/27/2020    2     0.764 2/5/2020 
    # 3 A     2/5/2020     3     0.544 2/13/2020
    # 4 A     2/13/2020    2.5   0.497 2/20/2020
    # 5 A     2/20/2020    1.5   0.613 2/20/2020
    # 6 B     2/1/2020     3     0.538 2/8/2020 
    # 7 B     2/8/2020     2.5   0.599 2/12/2020
    # 8 B     2/12/2020    1     0.257 2/12/2020
    # 9 C     1/30/2020    0.5   0.692 1/30/2020
    #10 D     2/6/2020    NA     0.449 2/17/2020
    #11 D     2/17/2020   14     0.185 2/26/2020
    #12 D     2/26/2020   11.5   0.274 3/3/2020 
    #13 D     3/3/2020     9.5   0.781 3/3/2020 
    

    【讨论】:

    • 效果很好,谢谢。对于它们相同的情况(当前为 NA 值),有没有办法将 start_date 值放入 end_date 中?
    • 是的,我们可以在lead 中添加default 值。更新了答案。
    【解决方案2】:

    使用data.table

    library(data.table)
    setDT(df)[, .(start_date = first(date),
                  score = first(score),
                  measure = mean(measure)), 
                 by = .(ID, grp = cumsum(!is.na(score)))
            ][, end_date := shift(start_date, type= 'lead', fill = last(start_date))
              ][, grp := NULL][]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-30
      • 2021-01-19
      • 1970-01-01
      • 2013-10-06
      • 1970-01-01
      • 2016-11-09
      • 2018-12-14
      • 1970-01-01
      相关资源
      最近更新 更多