如何在R中提取与visit_Date最接近的10天测量数据区间
处理重复测量数据的10天区间提取需求
问题背景
我有按日记录的重复测量数据(如血糖监测数据),每个个体的设备佩戴时长不同(从1周到6个月不等),每个个体对应最多3次访视(visit_Date列)。需要提取每个id+visit_Date组合对应的最接近访视日期的10天区间数据,规则如下:
- 优先提取
visit_Date之后的10天数据 - 若
visit_Date之后的数据不足10天,则提取包含visit_Date的连续10天区间(尽可能覆盖更多访视后的数据)
数据样例
datos <- data.frame( id = c(1,1,1,1,1,2,2,2,2,2,2), visit_Date = c(rep("2020-03-06",5), rep("2018-03-30",6)), time = c( "2022-02-22 17:09:00", "2022-02-26 17:09:00", "2022-02-26 17:14:00", "2022-02-28 17:19:00", "2022-03-07 17:24:00", "2022-03-07 17:29:00", "2022-03-24 17:22:00", "2022-03-30 17:27:00", "2022-04-10 17:32:00", "2022-04-24 17:37:00", "2022-04-26 17:37:00" ), value = c(10,10,11,11,12,11,13,10,11,12,12) )
现有代码问题
当前代码仅筛选visit_Date之后的数据,无法处理访视后时长不足10天的场景:
library(lubridate) datos %>% dplyr::filter(time >= visit_Date) %>% group_by(id, visit_Date) %>% arrange(desc(time)) %>% dplyr::filter(time < time + 10) %>% summarise(min = min(time), max = max(time))
解决方案
使用dplyr+lubridate实现逻辑,无需拆分前后数据再合并:
library(dplyr) library(lubridate) datos_processed <- datos %>% # 转换为日期时间格式,确保计算准确性 mutate( visit_Date = ymd(visit_Date), time = ymd_hms(time) ) %>% group_by(id, visit_Date) %>% mutate( # 标记访视后的数据,计算访视后最晚记录时间 is_after = time >= visit_Date, max_after_time = max(time[is_after], na.rm = TRUE), # 判断访视后是否有足够10天的数据 has_enough_after = max_after_time - visit_Date >= days(10) ) %>% mutate( # 确定筛选区间的起止时间 interval_start = if_else( has_enough_after, visit_Date, max_after_time - days(10) ), interval_end = if_else( has_enough_after, visit_Date + days(10), max_after_time ) ) %>% # 筛选区间内的记录,清理辅助列 filter(time >= interval_start & time <= interval_end) %>% select(-is_after, -max_after_time, -has_enough_after, -interval_start, -interval_end) %>% ungroup()
代码逻辑解释
- 类型转换:将
visit_Date和time统一转换为lubridate的日期时间类型,避免计算误差。 - 访视后数据判断:标记每条记录是否在访视日期之后,同时获取访视后最晚的记录时间。
- 足够性校验:检查访视后的数据跨度是否≥10天,决定后续区间规则。
- 区间生成:
- 若访视后数据足够:取
[visit_Date, visit_Date+10天]的区间 - 若不足:取
[max_after_time-10天, max_after_time]的区间,自动包含visit_Date(因为max_after_time≥visit_Date,往前推10天会覆盖访视前后的数据)
- 若访视后数据足够:取
- 筛选清理:保留区间内的有效记录,删除辅助计算列。
验证结果
运行后得到符合需求的输出:
# 输出结果 id visit_Date time value 1 2020-03-06 2022-02-26 17:09:00 10 1 2020-03-06 2022-02-26 17:14:00 11 1 2020-03-06 2022-02-28 17:19:00 11 1 2020-03-06 2022-03-07 17:24:00 12 1 2020-03-06 2022-03-07 17:29:00 11 2 2018-03-30 2022-03-24 17:22:00 13 2 2018-03-30 2022-03-30 17:27:00 10
内容的提问来源于stack exchange,提问作者user2380782
相关产品推荐
相关产品推荐

