我有一个包含事件列表的数据库。每个事件都有一个相关的开始日期,以及事件结束或完成的日期,例如:
dataset <- tibble(
eventid = sample(1:100, 25, replace=TRUE),
start_date = sample(seq(as.Date('2011/01/01'), as.Date('2012/01/01'), by="day"), 25),
completed_date = sample(seq(as.Date('2012/01/01'), as.Date('2014/01/01'), by="day"), 25)
)
> dataset
# A tibble: 25 x 3
eventid start_date completed_date
<int> <date> <date>
1 57 2011-01-14 2013-01-07
2 97 2011-01-21 2011-03-03
3 58 2011-01-26 2011-02-05
4 25 2011-03-22 2013-07-20
5 8 2011-04-20 2012-07-16
6 81 2011-04-26 2013-03-04
7 42 2011-05-02 2012-01-16
8 77 2011-05-03 2012-08-14
9 78 2011-05-21 2013-09-26
10 49 2011-05-22 2013-01-04
# ... with 15 more rows
>
我正试图制作一个滚动的";快照";在不同的时间点(例如逐月(有多少任务处于挂起状态。预期结果:
# A tibble: 25 x 2
month count
<date> <int>
1 2011-01-01 0
2 2011-02-01 3
3 2011-03-01 2
4 2011-04-01 2
5 2011-05-01 4
6 2011-06-01 8
我曾尝试使用group_by(period=floor_date(start_date,"month"))
对变量进行分组,但我有点卡住了,希望能有一个指向正确方向的指针!
如果可能的话,我更喜欢使用dplyr的解决方案。
谢谢!
您可以使用map2
从purrr
展开日期范围中包含的每个月的行。map2
将同时对多个输入进行迭代。在这种情况下,它将同时遍历开始日期和结束日期。
在每次迭代中,if将使用seq
(或seq.Date
(创建一个从开始到结束的月份序列(根据floor_date
确定(。结果是为每一行数据嵌套的(因为一行的序列中可能有多个月(。因此,之后需要unnest
。
transmute
将添加一个名为month_year
的新变量(并删除旧变量(,并使用substr
仅提取年份和月份(无日期(。这是日期的第一个到第七个字符。
然后,您可以group_by
表示月份年份,count
表示每个month_year
的挂起项目数。
我包含了set.seed
,以便从下面的数据中进行复制。
library(dplyr)
library(tidyr)
library(purrr)
library(lubridate)
dataset %>%
mutate(month = map2(floor_date(start_date, "month"),
floor_date(completed_date, "month"),
seq.Date,
by = "month")) %>%
unnest(month) %>%
transmute(month_year = substr(month, 1, 7)) %>%
group_by(month_year) %>%
summarise(count = n())
输出
month_year count
<chr> <int>
1 2011-01 1
2 2011-02 3
3 2011-03 9
4 2011-04 10
5 2011-05 13
6 2011-06 15
7 2011-07 16
8 2011-08 18
9 2011-09 19
10 2011-10 20
# … with 22 more rows
如果要排除已完成的月份(除非开始月份和已完成月份相同,如果存在的话(,可以从创建的月份序列中减去1个月。在这种情况下,您可以使用pmax
,这样,如果开始和结束月份相同,它仍然会计算月份(。
这是用map2
:修改的mutate
mutate(month = map2(floor_date(start_date, "month"),
pmax(floor_date(completed_date, "month") - 1, floor_date(start_date, "month")),
seq.Date,
by = "month"))
数据
set.seed(123)
dataset <- tibble(
eventid = sample(1:100, 25, replace=TRUE),
start_date = sample(seq(as.Date('2011/01/01'), as.Date('2012/01/01'), by="day"), 25),
completed_date = sample(seq(as.Date('2012/01/01'), as.Date('2014/01/01'), by="day"), 25)
)