如何在R中按月份分组统计员工起止日期间的工作日数
批量计算员工各月工作日数并转宽表(R实现)
输入数据
初始数据集包含员工编号、入职日期和离职日期:
df <- data.frame( employee_number = c(1001, 1002, 1003), start_date = as.Date(c('2023-01-15', '2023-02-10', '2023-03-05')), end_date = as.Date(c('2023-03-10', '2023-04-20', '2023-06-15')) )
预定义节假日列表:
holidays <- as.Date(c("2023-01-02", "2023-04-07", "2023-04-10", "2023-05-01", "2023-05-08", "2023-05-29", "2023-08-28"))
完整解决方案代码
library(dplyr) library(lubridate) library(tidyr) # 1. 为每个员工生成日期序列并过滤有效工作日 df_processed <- df %>% rowwise() %>% # 生成员工在职期间的所有日期 mutate(dates = list(seq(start_date, end_date, by = "days"))) %>% unnest(dates) %>% # 排除周末和节假日 filter(!wday(dates) %in% c(1,7) & !dates %in% holidays) %>% # 生成年月格式的周期列 mutate(period = paste(year(dates), str_pad(month(dates), 2, pad = "0"), sep = "-")) %>% # 按员工编号和周期分组统计工作日数 group_by(employee_number, period) %>% summarise(working_days = n(), .groups = "drop") # 2. 转换为宽格式,填充缺失月份为0 df_result <- df_processed %>% pivot_wider( id_cols = employee_number, names_from = period, values_from = working_days, values_fill = 0 ) %>% # 按月份顺序排序列 select(employee_number, sort(colnames(.)[-1])) # 查看结果 df_result
代码步骤说明
- 生成日期序列:通过
rowwise()+mutate(list(seq(...)))为每个员工生成在职期间的所有日期,再用unnest()展开为长格式数据。 - 过滤有效工作日:用
wday()判断排除周末(周日=1,周六=7),同时排除预定义的节假日。 - 分组统计:按员工编号和年月周期分组,统计每个周期内的有效工作日数。
- 转宽格式:使用
pivot_wider()将长格式转换为要求的宽格式,values_fill = 0确保没有工作日的月份填充为0,最后按月份排序列保证结果有序。
输出结果
运行代码后得到的结果与预期一致:
# A tibble: 3 × 7 employee_number `2023-01` `2023-02` `2023-03` `2023-04` `2023-05` `2023-06` <dbl> <int> <int> <int> <int> <int> <int> 1 1001 12 20 8 0 0 0 2 1002 0 13 23 12 0 0 3 1003 0 0 20 18 20 11
内容的提问来源于stack exchange,提问作者MathsUndergrad
相关产品推荐
相关产品推荐

