如何使用ivs包从工作时间区间中扣除休假时间区间?
用ivs包从工作时段中剔除休假重叠区间
要实现从工作时段中扣除重叠的休假时段,ivs包的iv_setdiff()函数是核心解决方案,结合分组与区间合并,具体操作如下:
数据预处理
先将时间列转换为日期时间格式,并创建区间对象:
library(tidyverse) library(ivs) # 读取并清洗数据 worked <- read.csv("https://www.dropbox.com/scl/fi/ctu6d8nb193ub0t5wawdf/worked.csv?rlkey=3zsbe8gh483hb0daazrrwl9ko&dl=1") %>% mutate(across(c(start, end), as.POSIXct)) %>% mutate(work_interval = iv(start, end)) vacation <- read.csv("https://www.dropbox.com/scl/fi/xn76ojwmewpcz71tcivgs/vacation.csv?rlkey=kmllrgvgr6ix0z2wq6roxin8f&dl=1") %>% mutate(across(c(start, end), as.POSIXct)) %>% mutate(vac_interval = iv(start, end))
核心处理:剔除重叠区间
按人员分组,先合并同一人员的工作/休假区间,再用区间减法得到有效工作时段:
# 合并同一人员的工作区间(你已完成此步骤) merged_work <- worked %>% group_by(person_id) %>% summarise(work_interval = iv_union(work_interval)) # 合并同一人员的休假区间 merged_vac <- vacation %>% group_by(person_id) %>% summarise(vac_interval = iv_union(vac_interval)) # 执行区间减法,剔除重叠部分 final_result <- merged_work %>% left_join(merged_vac, by = "person_id") %>% mutate(actual_work = iv_setdiff(work_interval, vac_interval)) %>% unnest(actual_work) %>% # 将多区间拆分为单行 mutate( actual_start = iv_start(actual_work), actual_end = iv_end(actual_work) ) %>% select(person_id, actual_start, actual_end, actual_work) # 查看某人员的示例结果 filter(final_result, person_id == 1)
关键函数说明
iv_union():合并同一人员的重叠或相邻区间,避免重复计算重叠部分iv_setdiff():从工作区间集合中减去所有与休假区间重叠的部分,返回剩余的有效工作时段,这就是实现"剔除"的核心操作unnest():将每个人员的多个结果区间展开为单独行,便于后续分析或导出
内容的提问来源于stack exchange,提问作者st4co4
相关产品推荐
相关产品推荐

