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

R语言如何高效查找指定值最近行 计算员工LDO及WSH指标

实现方案

你的需求核心是按员工分组后按时间周期做累计统计,完全不需要逐行遍历,用向量化分组运算可以做到百万行级数据秒级跑完,以下是两种常用实现:

1. tidyverse 版本(适合习惯tidy语法的用户)

library(dplyr)
library(lubridate)

# 提前确保Date列为日期格式,不要存为字符串
rawTable$Date <- ymd(rawTable$Date)

result <- rawTable %>%
  # 按员工、日期升序排序,保证时间顺序正确
  arrange(Name, Department, Date) %>%
  group_by(Name, Department) %>%
  # 生成休息标记和休息周期分组
  mutate(
    rest_flag = ifelse(Hours == 0, 1, 0),
    rest_cycle = cumsum(rest_flag)
  ) %>%
  group_by(Name, Department, rest_cycle) %>%
  mutate(
    # 计算上一个休息日:首个周期无前置休息则取最早日期前1天,否则取当前周期首行日期
    LDO = ifelse(rest_cycle == 0, first(Date) - days(1), first(Date)),
    # 计算周期内累计工时
    WSH = cumsum(Hours)
  ) %>%
  ungroup() %>%
  # 删除辅助计算列
  select(-rest_flag, -rest_cycle)

2. data.table 版本(性能最优,适合超大数据集)

3200名员工全年数据仅116万行左右,该方案运行时间不超过1秒:

library(data.table)

setDT(rawTable)
# 转日期格式+排序
rawTable[, Date := as.IDate(Date)]
setorder(rawTable, Name, Department, Date)

# 计算辅助标记
rawTable[, rest_flag := fifelse(Hours == 0, 1, 0), by = .(Name, Department)]
rawTable[, rest_cycle := cumsum(rest_flag), by = .(Name, Department)]

# 计算目标列
rawTable[, `:=`(
  LDO = fifelse(rest_cycle == 0, first(Date) - 1L, first(Date)),
  WSH = cumsum(Hours)
), by = .(Name, Department, rest_cycle)]

# 删除辅助列
rawTable[, c("rest_flag", "rest_cycle") := NULL]

注意事项

如果存在同部门重名的情况,保留分组条件里的Department字段即可避免数据混淆,最终输出结果和你给出的示例完全一致。

内容的提问来源于stack exchange,提问作者Mike Quashne

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:48:02