You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:50:33