如何用tidyverse按条件连接DataFrame?护理治疗数据筛选需求
匹配护理连续体与首次治疗时长的解决方案
需求明确:从Persons和Treatments数据集中,提取每个人每个护理连续体启动后首次接受治疗的时长,需满足:
- 治疗日期不得早于对应护理连续体的启动日期(
treatment_date >= continuum_start); - 仅保留每组中治疗日期与启动日期差值最小的记录(即首次符合条件的治疗)。
数据集说明
- Persons数据集:存储人员的护理连续体信息,核心字段包括
person_id(人员唯一标识)、continuum_start(护理连续体启动日期)。 - Treatments数据集:存储人员的治疗记录,核心字段包括
person_id(关联人员ID)、treatment_date(治疗日期)、treatment_hours(治疗时长,单位:小时)。
R代码实现
library(tidyverse) library(lubridate) # 读取并预处理数据集 persons <- read.csv("https://www.dropbox.com/s/5ziygvwnbvq73fc/persons.csv?dl=1") %>% mutate(continuum_start = ymd(continuum_start)) %>% select(-1) treatments <- read.csv("https://www.dropbox.com/s/0nfokiheo43lwjy/treatments.csv?dl=1") %>% mutate(treatment_date = ymd(treatment_date)) %>% select(-1) # 核心处理逻辑 final_result <- persons %>% # 按人员ID关联两个数据集 inner_join(treatments, by = "person_id") %>% # 筛选符合时间要求的治疗记录 filter(treatment_date >= continuum_start) %>% # 计算治疗日期与护理启动日的间隔天数(确保跨月计算准确) mutate(days_interval = as.duration(treatment_date - continuum_start) / ddays(1)) %>% # 按人员ID+护理启动日分组,提取间隔最小的首次治疗记录 group_by(person_id, continuum_start) %>% slice_min(days_interval, n = 1, with_ties = FALSE) %>% ungroup() %>% # 整理输出字段 select(person_id, continuum_start, first_treatment_date = treatment_date, first_treatment_hours = treatment_hours) # 查看最终结果 final_result
代码说明
- 关联数据集:使用
inner_join确保只保留同时存在护理连续体记录和治疗记录的人员; - 时间筛选:通过
filter过滤掉护理启动前的无效治疗记录; - 间隔计算:用
as.duration计算日期间隔,避免普通减法在跨月时的误差; - 提取首次记录:
slice_min直接按间隔天数取每组第一条记录,with_ties = FALSE确保即使同一天有多个治疗,也只保留一条(若需保留所有同日记录,可改为filter(days_interval == min(days_interval))); - 字段重命名:将输出字段调整为更直观的名称,方便后续查看。
内容的提问来源于stack exchange,提问作者st4co4
相关产品推荐
相关产品推荐

