我如何使用 dplyr 和 lubridate 包来计算一系列给定日期的活动记录?

How can I use dplyr and lubridate packages to count active records by a series of given dates?

我正在使用的包:

我正在处理的起始数据集:

Employee_ID      Start_Date      End_Date
1                2/1/2013        12/31/9999
2                5/14/2013       10/5/2017
3                9/7/2014        8/30/2017

我要从起始数据集创建的数据集:

Date             Active_Employee_Count
12/31/2013       2
12/31/2014       3
12/31/2015       3
12/31/2016       3
12/31/2017       1

说明

我希望能够获得每年 12 月 31 日的在职员工人数。我正在使用 dplyr 和 lubridate 包来尝试执行此操作,但我正在努力。我知道过滤器、group_by、总结、变异和不同的功能,但我不确定这些是否足以完成此任务。我面临的主要挑战是如何在 12 月 31 日这些日期以某种方式参与流程?我是否需要创建某种日期数组(2013 年 12 月 31 日、2014 年 12 月 31 日等),然后以某种方式使用它来执行此操作?

所以,我把员工的ID改成了实名

df = data.frame(Employee_ID = c("John", "Hugh", "Jack"),
                Start_Date = mdy(c(02012013, 05142013, 09072014)),
                End_Date = mdy(c(12319999, 10052017, 08302017)))  

Years_End2 = data.frame(Employee_ID = rep(df$Employee_ID, each = dim(Years_End)[1]),
                        Years_End = seq(from = mdy(12312013), to = mdy(12312017), by = "year"))

df %>% left_join(Years_End2, by = "Employee_ID") %>%
      mutate(Active = (End_Date > Years_End & Start_Date < Years_End)) %>%
      group_by(Years_End) %>%
      summarise(sum(Active))

  Years_End  `sum(Active)`
  <date>             <int>
1 2013-12-31             2
2 2014-12-31             3
3 2015-12-31             3
4 2016-12-31             3
5 2017-12-31             1

您可以使用 tidyr::expand() 以及 lubridate 中的 %within%%--% 运算符非常简洁地完成此操作。 %--% 本质上包裹了 lubridate::interval(),您可以使用 %within% 来测试日期是否在某个时间间隔内。

df <- data.frame(Employee_ID = c(1, 2, 3),
                Start_Date = mdy(c(02012013, 05142013, 09072014)),
                End_Date = mdy(c(12319999, 10052017, 08302017)))

df %>% 
  mutate(year = Start_Date) %>%
  expand(nesting(Employee_ID, Start_Date, End_Date), 
         year = seq.Date(from = ymd("2013-12-31"), to = ymd("2017-12-31"), by = "year")) %>%
  mutate(inrange = year %within% (Start_Date %--% End_Date)) %>%
  group_by(year) %>%
  summarize(active_employee_count = sum(inrange))

# A tibble: 5 x 2
  year       active_employee_count
  <date>                     <int>
1 2013-12-31                     2
2 2014-12-31                     3
3 2015-12-31                     3
4 2016-12-31                     3
5 2017-12-31                     1