如何用R计算每日在职员工的累计工作时长
问题解决与实现方案
一、修复员工在职状态识别问题
现有代码无法展示员工8数据的核心原因是空的end_date转换为NA后,interval无法正确识别在职状态。需先处理end_date_ymd的NA值,将在职员工的结束日期设为日期范围的最后一天:
library(tidyverse) library(lubridate) # 读取数据 DATES = read_excel(fname) # 定义日期范围(改用seq生成连续日期,避免原方法的潜在问题) date_range = seq(as_date(mdy("1-1-20")), as_date(mdy("1-1-23")), by = "day") # 处理日期列,修复NA的end_date DATES = DATES %>% mutate( start_date_ymd = ymd(start_date), # 把在职员工的end_date设为日期范围的最后一天 end_date_ymd = ifelse(is.na(ymd(end_date)), max(date_range), ymd(end_date)) %>% ymd() ) %>% select(-start_date, -end_date) %>% mutate(work_interval = interval(start_date_ymd, end_date_ymd))
修正后,x %within% work_interval就能正确识别所有在职(含未离职)员工,员工8的工作状态会被正常统计。
二、计算每日在职员工累计工作时长
累计工作时长指当日所有在职员工各自已工作的天数之和,实现步骤如下:
# 生成日期与员工的全组合,确保每个日期对应所有员工 daily_worker_data = expand_grid( date = date_range, employee_id = DATES$employee_id, # 替换为你的员工ID列名 start_date_ymd = DATES$start_date_ymd, end_date_ymd = DATES$end_date_ymd ) # 计算每日累计工作时长 daily_total_days = daily_worker_data %>% # 筛选当日在职的员工 filter(date >= start_date_ymd, date <= end_date_ymd) %>% # 计算单个员工到当日的工作天数(+1是包含入职当天,按需调整) mutate(days_worked = as.numeric(date - start_date_ymd) + 1) %>% # 按日期分组求和 group_by(date) %>% summarise(total_accum_days = sum(days_worked)) %>% ungroup()
三、可视化实现(分组面积图+离职标记)
用面积图展示累计时长趋势,同时标记资深员工的离职日期(假设资深员工为入职早于2019年1月1日的员工,可按需调整筛选规则):
# 提取资深员工的离职日期 senior_terminations = DATES %>% filter(start_date_ymd < ymd("2019-01-01"), end_date_ymd != max(date_range)) %>% select(employee_id, end_date_ymd) # 绘制可视化图表 ggplot() + # 面积图展示累计时长趋势 geom_area(data = daily_total_days, aes(x = date, y = total_accum_days), fill = "#4285F4", alpha = 0.6) + # 用虚线标记资深员工离职日期 geom_vline(data = senior_terminations, aes(xintercept = end_date_ymd), color = "#DB4437", linetype = "dashed") + # 添加离职员工标注 geom_text(data = senior_terminations, aes(x = end_date_ymd, y = max(daily_total_days$total_accum_days), label = paste("员工", employee_id, "离职")), angle = 90, vjust = 1.2, hjust = 0, color = "#DB4437", size = 3.5) + labs(x = "日期", y = "累计工作天数总和", title = "每日在职员工累计工作时长趋势") + theme_minimal()
四、原员工数量统计绘图的修复
如果仅需修复原有的在职员工数量统计,替换end_date_ymd的处理逻辑后重新运行即可:
# 修复后的员工数量统计 num_workers<- sapply(date_range, function(x) sum(x %within% DATES$work_interval)) tibble(date_range, num_workers) %>% ggplot(aes(x=date_range, y=num_workers)) + geom_point(color = "#4285F4") + geom_line(color = "#4285F4") + # 添加折线更清晰展示趋势 theme_minimal()
内容的提问来源于stack exchange,提问作者lonestar21
相关产品推荐
相关产品推荐

