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

在R语言中如何基于起止时间创建时间直方图并统计时段在岗员工数

嘿,这两个需求用R的tidyverse工具链就能完美解决,我一步步给你讲清楚~

首先咱们先把你的数据转成R里能正确识别的格式,用lubridate包处理时间超方便:

library(tidyverse)
library(lubridate)

# 构建你的员工数据框
DF <- tibble(
  EmployeeNum = c(123, 342, 876),
  Start_datetime = ymd_hms(c("2012-02-01 07:30:00", "2012-02-01 08:00:00", "2012-02-01 10:45:00")),
  End_datetime = ymd_hms(c("2012-02-01 17:45:00", "2012-02-01 17:45:00", "2012-02-01 18:45:00"))
)

1. 统计每天每小时的在岗员工数量

这个需求的核心是:找出每个小时区间内,有多少员工的工作时间覆盖了这个小时。咱们分三步来做:

步骤1:生成需要统计的所有小时区间

首先确定统计的时间范围,从最早的工作开始时间的整点,到最晚的工作结束时间的整点,每小时生成一个区间:

# 确定时间范围的首尾整点
min_time <- floor_date(min(DF$Start_datetime), "hour")
max_time <- ceiling_date(max(DF$End_datetime), "hour")

# 生成所有要统计的小时区间,整理成日期+小时的格式
hourly_intervals <- tibble(Hour_start = seq(min_time, max_time, by = "hour")) %>%
  mutate(
    Date = as.Date(Hour_start),
    Hour = format(Hour_start, "%H:%M"), # 转成你要的00:00格式
    Hour_end = Hour_start + hours(1)
  )

步骤2:匹配每个员工覆盖的小时区间

对每个员工,找出他们工作期间覆盖的所有完整小时,然后把这些小时和员工ID关联起来:

employee_hours <- DF %>%
  rowwise() %>%
  mutate(
    # 生成该员工工作期间的所有整点小时
    covered_hours = list(seq(floor_date(Start_datetime, "hour"), 
                             ceiling_date(End_datetime, "hour") - hours(1), 
                             by = "hour"))
  ) %>%
  unnest(covered_hours) %>% # 把列表展开成每行一个小时
  mutate(
    Date = as.Date(covered_hours),
    Hour = format(covered_hours, "%H:%M")
  ) %>%
  select(EmployeeNum, Date, Hour)

步骤3:统计每个小时的在岗人数

最后把生成的小时区间和员工覆盖的小时合并,统计每个小时的员工数,同时确保即使某个小时没人在岗,也会显示0:

final_stats <- hourly_intervals %>%
  select(Date, Hour) %>%
  left_join(employee_hours %>% count(Date, Hour, name = "NumberofEmployeesWorking"), 
            by = c("Date", "Hour")) %>%
  mutate(NumberofEmployeesWorking = replace_na(NumberofEmployeesWorking, 0)) %>%
  arrange(Date, Hour)

# 查看结果
print(final_stats)

运行后你会得到完全符合要求的输出格式,比如2012-02-01的07:00会有1个员工(123号),08:00开始有2个,以此类推。


2. 创建工作时间区间的时间直方图

这里有两种常见的展示方式,根据你的需求选就行:

方式1:按小时统计的柱状直方图

直接用上面生成的employee_hours数据,统计每个小时的在岗人数,画成柱状图:

ggplot(employee_hours, aes(x = Hour)) +
  geom_bar(fill = "#2ecc71", width = 0.8) +
  labs(
    title = "Hourly Count of Working Employees",
    x = "Hour of Day",
    y = "Number of Employees"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) # 让小时标签倾斜,避免重叠

如果你的数据有多天,还可以按日期分面展示:

ggplot(employee_hours, aes(x = Hour)) +
  geom_bar(fill = "#3498db", width = 0.8) +
  facet_wrap(~Date) + # 按日期拆分面板
  labs(
    title = "Hourly Employee Count by Date",
    x = "Hour of Day",
    y = "Number of Employees"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

方式2:展示每个员工的工作区间(叠加式)

如果想更直观看到每个员工的工作时间段分布,可以用线段图展示:

DF %>%
  mutate(EmployeeID = factor(EmployeeNum)) %>%
  ggplot(aes(y = EmployeeID, x = Start_datetime, xend = End_datetime)) +
  geom_segment(size = 3, color = "#e74c3c") +
  labs(
    title = "Employee Work Time Intervals",
    x = "Datetime",
    y = "Employee Number"
  ) +
  theme_minimal()

这个图能清晰看到每个员工的起止时间,以及不同员工的工作时间重叠情况。


内容的提问来源于stack exchange,提问作者Essi Shams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:34:15