如何从Visits DataFrame提取观测日期6个月±15天的重要值至观测表
解决方案:匹配6个月±15天内的重要访问值
方法一:使用dplyr(Tidyverse风格)
先修正时间窗口为需求的±15天,再通过关联、筛选、排序找到每个观测对象最接近目标日期的访问记录:
library(dplyr) library(lubridate) # 1. 修正目标日期及允许的时间窗口(±15天) observations <- observations %>% mutate( target_date = observation_date + days(180), window_start = target_date - days(15), window_end = target_date + days(15) ) # 2. 关联数据集并筛选时间范围内的访问记录 matched_data <- inner_join(visit_data, observations, by = c("visit_observation_id" = "observation_id")) %>% filter(visit_date >= window_start & visit_date <= window_end) %>% # 计算访问日期与目标日期的天数差绝对值 mutate(date_diff = abs(as.numeric(visit_date - target_date))) %>% # 按观测对象分组,取天数差最小的第一条记录 group_by(observation_id) %>% arrange(date_diff, .by_group = TRUE) %>% slice_head(n = 1) %>% ungroup() %>% select(observation_id, important_value) # 3. 将匹配结果合并回原观测数据集 observations <- observations %>% left_join(matched_data, by = "observation_id") %>% rename(observation_date_6months_later_important_value = important_value)
方法二:使用data.table(适合大数据量场景)
如果数据集规模较大,data.table的运算效率更优:
library(data.table) library(lubridate) # 转换为data.table格式 setDT(observations) setDT(visit_data) # 计算目标日期及时间窗口 observations[, `:=`( target_date = observation_date + days(180), window_start = target_date - days(15), window_end = target_date + days(15) )] # 关联并筛选,取每个观测对象最接近目标日期的记录 matched_dt <- visit_data[observations, on = .(visit_observation_id = observation_id)][ visit_date >= window_start & visit_date <= window_end, .(date_diff = abs(as.numeric(visit_date - target_date)), important_value), by = .(observation_id) ][order(date_diff), .SD[1], by = observation_id] # 合并结果到原数据集 observations[matched_dt, on = "observation_id", observation_date_6months_later_important_value := important_value]
关键说明
- 若某个观测对象在±15天窗口内无访问记录,对应列将保留
NA,符合初始设置 - 若同一观测对象在窗口内有多个访问记录天数差相同(如同一天的多次访问),可将
slice_head(n=1)替换为summarise(important_value = mean(important_value))取均值,或根据需求选择最大值/最小值 - 用
lubridate::days()确保日期运算的准确性,避免因月份天数差异导致的误差
内容的提问来源于stack exchange,提问作者MDStat
相关产品推荐
相关产品推荐

