根据日期查找超过一年的疗程休息时间

Find treatment course breaks longer than a year based on dates

我有一个包含 ID 和治疗日期的数据框,如下所示

ID  Dates
1   01/2/2012
1   02/8/2012
1   03/8/2012
1   04/5/2013
1   05/5/2013
2   01/2/2012
2   03/5/2013
2   04/6/2013

如果有超过一年的治疗日期中断,我需要为每个 ID 查找。如果是,那么我需要将它们分成两门课程,并列出开始和结束日期。所以执行 R 代码后,它将如下所示:

ID  Course1StarteDate  Course1EndDate Break1to2(Yr) Course2StartDate  Course2EndDate 
1   01/2/2012          03/8/2012      1.075         04/5/2013         05/5/2013
2   01/2/2012          01/2/2012      1.173         03/5/2013         04/6/2013

我的dataframe有几百个ID,不知道会有多少课程。有没有一种有效的方法可以使用 R 来解决这个问题?提前致谢!

如果 d 是您的数据,您可以确定一行日期与前一行日期之间的差异何时超过 365(或可能是 365.25),然后使用 cumsum 生成不同的疗程。最后添加一列,估计课程之间“休息”的持续时间。

as_tibble(d) %>% 
  group_by(ID) %>% 
  mutate(trt=as.numeric(Dates-lag(Dates)),
         trt=cumsum(if_else(is.na(trt),0,trt)>365)+1) %>% 
  group_by(ID,trt) %>% 
  summarize(StartDate = min(Dates),
            EndDate = max(Dates),.groups = "drop_last") %>% 
  mutate(Break:=as.numeric(lead(StartDate) - EndDate)/365)

输出:

     ID   trt StartDate  EndDate    Break
  <dbl> <dbl> <date>     <date>     <dbl>
1     1     1 2012-01-02 2012-03-08  1.08
2     1     2 2013-04-05 2013-05-05 NA   
3     2     1 2012-01-02 2012-01-02  1.17
4     2     2 2013-03-05 2013-04-06 NA   

我建议保持这种长格式,而不是像您在示例中那样转为宽格式,尤其是在有数百个 ID 的情况下,所有 ID 都可能包含不同数量的课程。长格式几乎总是更好。

但是,如果你真的想要这个,你可以从上面继续管道,像这样:

  ungroup %>%
  pivot_wider(id_cols =ID,
              names_from = trt,
              values_from = c(StartDate:Break),
              names_glue = "Course{trt}_{.value}",
              names_vary = "slowest")

生成这种“宽幅”格式:

     ID Course1_StartDate Course1_EndDate Course1_Break Course2_StartDate Course2_EndDate Course2_Break
  <dbl> <date>            <date>                  <dbl> <date>            <date>                  <dbl>
1     1 2012-01-02        2012-03-08               1.08 2013-04-05        2013-05-05                 NA
2     2 2012-01-02        2012-01-02               1.17 2013-03-05        2013-04-06                 NA