计算每年两个日期之间的天数

Rom*_*ain 5 r date lubridate

我有一个数据框,每行都有开始日期和结束日期。我想计算两个日期之间的天数并按年份分割。所以从这里开始:

id <- c(1,2,3)
start <- as.Date(c('01/01/2015','01/01/2016','07/01/2015'), format = '%m/%d/%Y')
end <- as.Date(c('12/31/2016','12/31/2016','12/31/2016'), format = '%m/%d/%Y')
df <- data.frame(id, start, end)
Run Code Online (Sandbox Code Playgroud)
ID 开始 结尾
1 2015年1月1日 2016年12月31日
2 2016年1月1日 2016年12月31日
3 2015年1月7日 2016年12月31日

对此:

ID 开始 结尾 天_号。 2015年 2016年
1 2015年1月1日 2016年12月31日 第730章 365 365
2 2016年1月1日 2016年12月31日 365 0 365
3 2015年7月1日 2016年12月31日 第548章 183 365

感谢任何帮助,请注意我想动态计算年度统计数据,在我的实际案例中我可能会得到很多年的列...我猜 lubridate 可能会有所帮助,但我不确定从哪里开始。

Ben*_*Ben 1

tidyverse这是使用和 的一种方法lubridate

首先,按日历年分隔行,用于测量每年的天数。每行将包含每个日历年中要计算的日期,如果重叠多个年份,则从 1 月 1 日开始,到 12 月 31 日结束。然后,很容易计算出一年中有多少天。

这个例子的结果与我的结果略有不同。2016年是闰年,有366天。如果天数不包含开始日期或结束日期,您将得到不同的答案。

编辑 (6/8/23):根据下面的评论,为包含日期添加 1。这将为闰年(例如 2016 年)提供 366 天,为其他年份提供 365 天。

library(tidyverse)
library(lubridate)

df %>%
  mutate(date_int = interval(start, end),
         year = map2(year(start), year(end), seq)) %>%
  unnest(year) %>%
  mutate(year_int = interval(as.Date(paste0(year, '-01-01')), as.Date(paste0(year, '-12-31'))),
         year_sect = intersect(date_int, year_int),
         start_new = as.Date(int_start(year_sect)),
         end_new = as.Date(int_end(year_sect))) %>%
  select(id, start_new, end_new) %>%
  mutate(year = year(start_new),
         days = as.numeric(end_new - start_new) + 1) %>%
  right_join(df) %>%
  pivot_wider(id_cols = c(id, start, end), names_from = year, values_from = days, names_prefix = "year_", values_fill = list(days = 0)) %>%
  mutate(days_number = reduce(select(., starts_with("year_")), `+`))
Run Code Online (Sandbox Code Playgroud)

输出

     id start      end        year_2015 year_2016 days_number
  <dbl> <date>     <date>         <dbl>     <dbl>       <dbl>
1     1 2015-01-01 2016-12-31       365       366         731
2     2 2016-01-01 2016-12-31         0       366         366
3     3 2015-07-01 2016-12-31       184       366         550
Run Code Online (Sandbox Code Playgroud)