我有一个数据框,每行都有一个开始和结束日期。我想计算两个日期之间的天数并按年份拆分。 所以从这里开始:
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)
id | 开始 | 结束 |
---|---|---|
1 | 01/01/2015 | 12/31/2016 |
2 | 01/01/2016 | 12/31/2016 |
3 | 01/07/2015 | 12/31/2016 |
为此:
id | 开始 | 结束 | days_no. | year_2015 | year_2016 |
---|---|---|---|---|---|
1 | 01/01/2015 | 12/31/2016 | 730 | 365 | 365 |
2 | 01/01/2016 | 12/31/2016 | 365 | 0 | 365 |
3 | 07/01/2015 | 12/31/2016 | 548 | 183 | 365 |
感谢任何帮助,请注意我想动态计算年度统计数据,在我的实际案例中我可能会得到很多年份的列...我猜 lubridate 可能会有所帮助,但我不确定从哪里开始.
答案 0 :(得分:1)
这是一个基本的 R 选项
transform(
df,
days_no = end - start,
year_2015 = pmax(as.Date("2015-12-31") - start, 0),
year_2016 = pmax(end - as.Date("2016-1-1"), 0)
)
给出
id start end days_no year_2015 year_2016
1 1 2015-01-01 2016-12-31 730 days 364 days 365 days
2 2 2016-01-01 2016-12-31 365 days 0 days 365 days
3 3 2015-07-01 2016-12-31 549 days 183 days 365 days
答案 1 :(得分:0)
这是使用 tidyverse
和 lubridate
的一种方法。
首先,按日历年分隔行,以用于衡量每年的天数。每行将包括每个日历年要计算的日期,从 1 月 1 日开始,如果重叠多年,则从 12 月 31 日结束。然后,很容易计算给定年份的天数。
这个例子的结果与我所得到的略有不同。 2016年是闰年,有366天。如果天数不包括开始日期或结束日期,您会得到不同的答案。
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)) %>%
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_")), `+`))
输出
id start end year_2015 year_2016 days_number
<dbl> <date> <date> <dbl> <dbl> <dbl>
1 1 2015-01-01 2016-12-31 364 365 729
2 2 2016-01-01 2016-12-31 0 365 365
3 3 2015-07-01 2016-12-31 183 365 548