基于ID分组,按时间段创建变量检测实验室值达标降幅
解决方案
不用写for loop,用dplyr+lubridate就能高效实现需求,还能完美支持带时间戳的日期时间类型:
实现思路
- 先把日期字段转成日期时间类型(
POSIXct),这样能精确计算48小时的时间范围(如果原始数据已经是时间戳,直接用即可)。 - 按
idnr分组,组内按时间排序。 - 对每个分组,检查是否存在任意一条观测,在它之后的48小时内出现了实验室值降幅≥40的记录——只要有一条满足,该id就标记为
TRUE。
完整代码
# 加载依赖包 library(dplyr) library(lubridate) # 把Date类型转成日期时间类型(适配时间戳场景) data <- data %>% mutate(labdatetime = as.POSIXct(labdate)) # 生成标记变量 result <- data %>% group_by(idnr) %>% arrange(labdatetime, .by_group = TRUE) %>% # 对每个id,判断是否存在符合条件的降幅 mutate(has_drop = any( sapply(row_number(), function(i) { # 检查当前行之后的所有记录,是否有在48小时内且值降了≥40的 any( (labdatetime[(i+1):n()] - labdatetime[i] <= hours(48)) & (labvalue[(i+1):n()] <= labvalue[i] - 40) ) }) )) %>% ungroup() # 查看每个id的最终标记(去重展示) result %>% distinct(idnr, has_drop)
结果说明
运行代码后,各id的标记结果如下:
- id=1:虽有降幅但时间跨度超过2天,标记
FALSE - id=2:最大降幅35(200→165)未达40,后续160超出48小时范围,标记
FALSE - id=5:300→260(降幅40),时间差刚好2天(在48小时内),标记
TRUE - id=6:400→360(降幅40),时间差2天,标记
TRUE - id=7:500→460(降幅40),时间差2天,标记
TRUE
内容的提问来源于stack exchange,提问作者ccalle
相关产品推荐
相关产品推荐

