R根据日期之间的间隔/重叠计算数组中的总天数

R根据日期之间的间隔/重叠计算数组中的总天数,r,date,dplyr,R,Date,Dplyr,我有一个如下所示的数据框: id <- c("Joe" ,"Joe" ,"Joe" ,"Joe" ,"Joe") work_start <- as.Date(c("2004-06-23", "2005-04-20", "2005-05-24", "2014-05-01", "2018-04-01")) work_end <- as.Date(c("2014-04-30", "2010-03-11", "2005-07-05", "2018-03-31", "2019-03-31

我有一个如下所示的数据框:

id <- c("Joe" ,"Joe" ,"Joe" ,"Joe" ,"Joe")
work_start <- as.Date(c("2004-06-23", "2005-04-20", "2005-05-24", "2014-05-01", "2018-04-01"))
work_end <- as.Date(c("2014-04-30", "2010-03-11", "2005-07-05", "2018-03-31", "2019-03-31"))

df <- data.frame(id, work_start, work_end)
id last\u work\u end&is.finite(滞后(last\u work\u end)),
滞后(最后一次工作结束),
上次工作(结束))%>%
mutate(last_work_end=if_else(lag(last_work_end)>last_work_end&是有限的(lag(last_work_end)),
滞后(最后一次工作结束),
上次工作(结束))%>%
解组()
您可以尝试:

library(dplyr)

df <- df %>%
  arrange(id, work_start, work_end) %>%
  group_by(id) %>%
  mutate(cumMaxDate = setattr(cummax(unclass(work_end)), "class", "Date")) %>%
  group_by(id, idx = cumsum(+(work_start > (lag(cumMaxDate, default = first(cumMaxDate)) + 1)))) %>%
  summarise(work_start = min(work_start), work_end = max(cumMaxDate), duration = difftime(work_end, work_start)) %>%
  ungroup() %>% select(-idx)
输出:

# A tibble: 1 x 4
  id    work_start work_end   duration 
  <fct> <date>     <date>     <drtn>   
1 Joe   2004-06-23 2019-03-31 5394 days
   id work_start   work_end  duration
1 Joe 2004-06-23 2019-03-31 5394 days

请注意,该软件包仍处于早期阶段,但至少在相当程度上,
collapse\u ranges
功能已经过战斗测试-另一方面,如果您有任何改进建议或发现任何bug,欢迎您报告。

这里有一个使用data.table的选项

library(data.table)
setDT(df)[order(id, work_start, work_end), 
    g := cumsum(work_start - 1L > shift(cummax(as.integer(work_end)), fill=0L)), id][,
        c("first_work_start","last_work_end") := .(min(work_start), max(work_end)), .(id, g)]
输出:

    id work_start   work_end g first_work_start last_work_end
1: Joe 2004-06-23 2014-04-30 1       2004-06-23    2019-03-31
2: Joe 2005-04-20 2010-03-11 1       2004-06-23    2019-03-31
3: Joe 2005-05-24 2005-07-05 1       2004-06-23    2019-03-31
4: Joe 2014-05-01 2018-03-31 1       2004-06-23    2019-03-31
5: Joe 2018-04-01 2019-03-31 1       2004-06-23    2019-03-31

参考资料:

仅仅计算
work\u end
work\u start
,然后将总工作日的差异相加,还不够吗?是的@arg0naut91这对于我需要它做的事情非常有效,让我在dplyr中四处奔波看起来很遗憾。我经常使用带有大量日期(和大量NA日期)的数据集,所以我将来一定会查看neatRanges!再次感谢
library(data.table)
setDT(df)[order(id, work_start, work_end), 
    g := cumsum(work_start - 1L > shift(cummax(as.integer(work_end)), fill=0L)), id][,
        c("first_work_start","last_work_end") := .(min(work_start), max(work_end)), .(id, g)]
    id work_start   work_end g first_work_start last_work_end
1: Joe 2004-06-23 2014-04-30 1       2004-06-23    2019-03-31
2: Joe 2005-04-20 2010-03-11 1       2004-06-23    2019-03-31
3: Joe 2005-05-24 2005-07-05 1       2004-06-23    2019-03-31
4: Joe 2014-05-01 2018-03-31 1       2004-06-23    2019-03-31
5: Joe 2018-04-01 2019-03-31 1       2004-06-23    2019-03-31