这几天我有点纠结。假设我有两个人。
人1在2000年1月1日至2001年3月1日的队列中。第2人在1999年1月1日至2001年12月31日的队列中。
这意味着,在2000年和2001年,1人都在队列中。1999年全年、2000年全年和2001年全年,第2人都在队列中。
加在一起意味着,1999年,这一群体总共贡献了1年的人时,2000年为2年人次,2001年为1.25年人次。
有人知道有什么R函数可以帮助像这样的日期之间的时间划分/相加吗?我可以从头开始写,但如果现有的功能存在,我想使用它们,而谷歌却没有给我任何帮助。
谢谢!
使用data.table
和lubridate
:
Data <- Data[, .(Start, Start2 = seq(Start, End, by="year"), End), by=.(Person)]
Data[, End2 := Start2+years(1)-days(1)]
Data[year(Start2) != year(Start), Start := Start2]
Data[year(End2) != year(End), End := End2]
Data[, c("Year", "Contribution") := list(year(Start), (month(End)-month(Start)+1)/12)]
Data <- Data[, .(Contribution = sum(Contribution)), by=.(Year)][order(Year)]
哪个给出:
> Data
Year Contribution
1: 1999 1.00
2: 2000 2.00
3: 2001 1.25
这是一种可能的广义tidyverse
方法,也使用lubridate
。这将为每年创建行,并为每个人年创建适当的时间间隔。日历年和人年间隔之间的交叉点将是最终总结的贡献。请注意,此处的1月1日至3月1日将被视为2个月或一年的1/6(而非25%(。
df <- data.frame(
person = c("Person 1", "Person 2"),
start = c("01/01/2000", "01/01/1999"),
end = c("01/03/2001", "31/12/2001")
)
df$start <- dmy(df$start)
df$end <- dmy(df$end)
library(lubridate)
library(tidyverse)
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)
) %>%
group_by(year) %>%
summarise(contribute = signif(sum(as.numeric(year_sect, "years")), 2))
输出
year contribute
<int> <dbl>
1 1999 1
2 2000 2
3 2001 1.2