R每天的行数

问题描述

我有一个数据帧,每行都有时间窗口。时间窗口由每个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

我正在寻找的输出是将其汇总为几天,每天都有ID的数量

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列,unnestlist列中获取相应的'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