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