【问题标题】:R inserting rows between dates by group based on second columnR根据第二列按组在日期之间插入行
【发布时间】:2020-05-05 16:00:14
【问题描述】:

我有一个看起来像这样的 df

ID    FINAL_DT      START_DT

23       NA        2020-03-20
25       NA        2020-04-10
29   2020-02-02    2020-01-23
30       NA        2020-01-02

我想做的是为每个 ID 添加一行,每个月从 START_DT 开始,到第一个 FINAL_DT 或当前日期结束。预期输出如下:

ID    FINAL_DT      START_DT      ACTIVE_MONTH

23       NA        2020-03-20       2020-03
23       NA            NA           2020-04
23       NA            NA           2020-05
25       NA        2020-04-10       2020-04
25       NA            NA           2020-05
29   2020-02-02    2020-01-23       2020-01
29   2020-02-02        NA           2020-02
30       NA        2020-01-02       2020-01
30       NA            NA           2020-02
30       NA            NA           2020-03 
30       NA            NA           2020-04
30       NA            NA           2020-05

我有以下代码可以工作,但不考虑 FINAL_DT

current_date = as.Date(Sys.Date())

enroll <- enroll %>%
          group_by(ID) %>% 
          complete(START_DATE = seq(START_DATE, current_date, by = "month"))

我尝试了以下方法,但我认为由于 NA 的原因而出现错误:

current_date = as.Date(Sys.Date())

enroll <- enroll %>%
          group_by(ID) %>% 
          complete(START_DATE = seq(START_DATE, min(FINAL_DT,current_date), by = "month"))

一个月中的哪一天也无关紧要,我不确定在之前还是之后删除它会更容易。

【问题讨论】:

    标签: r dataframe tidyr


    【解决方案1】:

    这是另一种方法。您可以使用floor_date 获取月份的第一天以在您的月份序列中使用。然后,您可以将完整序列包含到今天的日期,并根据FINAL_DT 进行过滤。如果您想要月份/年份对象,您可以使用 zoo 中的 as.yearmon

    library(zoo)
    library(tidyr)
    library(dplyr)
    library(lubridate)
    
    current_date = as.Date(Sys.Date())
    
    enroll %>%
      mutate(ACTIVE_MONTH = floor_date(START_DT, unit = "month")) %>%
      group_by(ID) %>%
      complete(ACTIVE_MONTH = seq.Date(floor_date(START_DT, unit = "month"), current_date, by = "month")) %>%
      filter(ACTIVE_MONTH <= first(FINAL_DT) | is.na(first(FINAL_DT))) %>%
      ungroup() %>%
      mutate(ACTIVE_MONTH = as.yearmon(ACTIVE_MONTH))
    

    输出

    # A tibble: 12 x 4
          ID ACTIVE_MONTH FINAL_DT   START_DT  
       <dbl> <yearmon>    <date>     <date>    
     1    23 Mar 2020     NA         2020-03-20
     2    23 Apr 2020     NA         NA        
     3    23 May 2020     NA         NA        
     4    25 Apr 2020     NA         2020-04-10
     5    25 May 2020     NA         NA        
     6    29 Jan 2020     2020-02-02 2020-01-23
     7    29 Feb 2020     NA         NA        
     8    30 Jan 2020     NA         2020-01-02
     9    30 Feb 2020     NA         NA        
    10    30 Mar 2020     NA         NA        
    11    30 Apr 2020     NA         NA        
    12    30 May 2020     NA         NA
    

    【讨论】:

      【解决方案2】:

      这是一种在lubridate 的帮助下为每个MONTH 返回行的方法。

      library(dplyr)
      library(tidyr)
      library(lubridate)
      current_date = as.Date(Sys.Date())
      
      enroll %>%
        mutate(MONTH = month(START_DT)) %>%
        group_by(ID) %>% 
        complete(MONTH = seq(MONTH, min(month(FINAL_DT)[!is.na(FINAL_DT)],month(current_date))))
      # A tibble: 12 x 4
      # Groups:   ID [4]
      #      ID MONTH FINAL_DT   START_DT  
      #   <int> <dbl> <fct>      <fct>     
      # 1    23     3 NA         2020-03-20
      # 2    23     4 NA         NA        
      # 3    23     5 NA         NA        
      # 4    25     4 NA         2020-04-10
      # 5    25     5 NA         NA        
      # 6    29     1 2020-02-02 2020-01-23
      # 7    29     2 NA         NA        
      # 8    30     1 NA         2020-01-02
      # 9    30     2 NA         NA        
      #10    30     3 NA         NA        
      #11    30     4 NA         NA        
      #12    30     5 NA         NA
      

      【讨论】:

      • 这很好,但我还需要附加月份的年份
      猜你喜欢
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多