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

使用dplyr处理HR人事数据:筛选行与补全非连续时间

处理HR岗位人事变动数据集的两个任务解决方案

以下基于R语言的tidyverse生态给出实操方案,假设你的数据集名为hr_data,且日期字段已转换为Date类型。


问题1:按positionID分组,保留第一个非NA exitCode及之后的所有行

先确保数据按岗位和变动时间排序,再标记并筛选目标行:

library(tidyverse)
library(lubridate)

# 处理问题1:保留每组第一个非NA exitCode及后续行
hr_data_cleaned <- hr_data %>%
  arrange(positionID, moveStartDate) %>%
  group_by(positionID) %>%
  mutate(
    # 标记从第一个非NA exitCode开始的所有行
    keep_flag = cumsum(!is.na(exitCode)) >= 1,
    # 若组内全为NA exitCode,默认保留所有行(可根据需求修改为FALSE)
    keep_flag = ifelse(all(is.na(exitCode)), TRUE, keep_flag)
  ) %>%
  filter(keep_flag) %>%
  select(-keep_flag) %>%
  ungroup()

关键逻辑说明

  • 先按positionID和moveStartDate排序,保证变动顺序正确
  • 用cumsum生成标记:从第一个非NA的exitCode开始,后续所有行都会被标记为TRUE
  • 针对全组无有效exitCode的情况,可自行调整是否保留

问题2:补同一positionID下的非连续时间段

基于问题1的结果,补全岗位变动间隙的空缺时间段:

# 处理问题2:补全岗位变动的时间间隙
hr_data_final <- hr_data_cleaned %>%
  arrange(positionID, moveStartDate) %>%
  group_by(positionID) %>%
  mutate(
    # 获取下一行的变动开始日期
    next_start = lead(moveStartDate),
    # 计算当前行结束到下一行开始的间隔天数
    gap_days = as.integer(next_start - moveEndDate)
  ) %>%
  # 筛选出需要补全的间隔(间隔>1天才算非连续)
  filter(gap_days > 1) %>%
  rowwise() %>%
  mutate(
    # 生成间隙内的所有日期
    fill_dates = list(seq(moveEndDate + days(1), next_start - days(1), by = "day")),
    # 补全行的业务字段(可根据实际需求调整)
    moveType = "岗位空缺",
    personID = NA,
    exitCode = NA
  ) %>%
  unnest(fill_dates) %>%
  # 对齐原数据的列结构
  rename(moveStartDate = fill_dates, moveEndDate = fill_dates) %>%
  select(names(hr_data_cleaned)) %>%
  ungroup() %>%
  # 合并原数据与补全行,重新排序
  bind_rows(hr_data_cleaned) %>%
  arrange(positionID, moveStartDate)

关键逻辑说明

  • 先计算每行与下一行的时间间隙,仅处理间隔超过1天的情况(连续日期无需补全)
  • 补全行的moveType设为"岗位空缺",personID和exitCode设为NA,可根据业务规则修改字段值
  • 最后合并原数据与补全行,保证整体时间序列连续

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:52:40