问题描述
我有一个数据帧,每行都有时间窗口。时间窗口由每个ID的开始日期和结束日期标识。 对于每个日历日,我想知道ID如何具有跨越该天的时间窗口。
示例数据
data <- data.frame(
id = c("A","B","C"),start_date = as.POSIXct(c("2020-01-01 01:00:00","2020-01-02 01:00:00","2020-01-03 01:00:00")),end_date = as.POSIXct(c("2020-01-04 01:00:00","2020-01-03 01:00:00","2020-01-06 01:00:00")),stringsAsFactors = FALSE
)
data
id start_date end_date
1 A 2020-01-01 01:00:00 2020-01-04 01:00:00
2 B 2020-01-02 01:00:00 2020-01-03 01:00:00
3 C 2020-01-03 01:00:00 2020-01-06 01:00:00
day number_of_ids
2020-01-01 1
2020-01-02 2
2020-01-03 3
2020-01-04 2
2020-01-05 1
2020-01-06 1
非常感谢任何帮助。
解决方法
我们在list
列,unnest
和list
列中获取相应的'start_date','end_date'之间的日期序列,然后按'day'进行分组并得到n_distinct
中与summarise
不同的'id'的数量
library(dplyr)
library(purrr)
library(tidyr)
data %>%
transmute(id,day = map2(as.Date(start_date),as.Date(end_date),~ seq(.x,.y,by = 'day'))) %>%
unnest(c(day)) %>%
group_by(day) %>%
summarise(number_of_ids = n_distinct(id))
# A tibble: 6 x 2
# day number_of_ids
# <date> <int>
#1 2020-01-01 1
#2 2020-01-02 2
#3 2020-01-03 3
#4 2020-01-04 2
#5 2020-01-05 1
#6 2020-01-06 1
,
在基数R中,您可以执行以下操作:
a <- with(data,setNames(Map( function(x,y) format(seq(x,y,'1 day'),'%F'),start_date,end_date),id))
aggregate(ind~values,stack(a),length)
values ind
1 2020-01-01 1
2 2020-01-02 2
3 2020-01-03 3
4 2020-01-04 2
5 2020-01-05 1
6 2020-01-06 1