You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言长格式数据集如何判断日期是否落在两次检测间隔内

问题背景

现有两个患者相关数据集:

  • tests:长格式存储的检测日期与检测结果数据,每位患者对应2条不同检测日期的记录
  • meds:存储患者的用药日期

示例数据如下:

(tests <- structure(list(id = c(1, 1, 2, 2, 3, 3), test_date = structure(c(10957, 
10963, 11001, 11035, 11091, 11230), class = "Date"), test_result = c(1, 
1, 0, 1, 0, 0)), row.names = c(NA, -6L), class = "data.frame"))

#>   id  test_date test_result
#> 1  1 2000-01-01           1
#> 2  1 2000-01-07           1
#> 3  2 2000-02-14           0
#> 4  2 2000-03-19           1
#> 5  3 2000-05-14           0
#> 6  3 2000-09-30           0

(meds <- structure(list(id = c(1, 2, 3), med_date = structure(c(10959, 
10956, NA), class = "Date")), row.names = c(NA, -3L), class = "data.frame"))

#>   id   med_date
#> 1  1 2000-01-03
#> 2  2 1999-12-31
#> 3  3       <NA>

需求为在tests数据集中新增一列,标记对应患者是否在两次检测的日期间隔内接受了药物治疗,预期输出如下:

#>   id  test_date test_result   received_med_within
#> 1  1 2000-01-01           1   TRUE
#> 2  1 2000-01-07           1   TRUE
#> 3  2 2000-02-14           0   FALSE
#> 4  2 2000-03-19           1   FALSE
#> 5  3 2000-05-14           0   FALSE
#> 6  3 2000-09-30           0   FALSE

最初设想的实现流程为:

  1. 将tests数据集通过pivoting转换为宽格式
  2. 通过left_join将meds数据集关联到宽表
  3. 使用if_else(med_date %within% interval(test_date_1, test_date_2), TRUE, FALSE)逻辑判断用药日期是否在检测间隔内
  4. 再将数据集转换回长格式

但该方案流程繁琐,真实场景下数据集包含更多字段时,长宽表转换操作复杂度较高,需要找到可直接在长格式数据集上完成日期区间判断的简洁方法。

实现方案

不需要做长宽表转换,直接按患者分组计算检测日期区间即可,基于dplyr的实现代码如下:

library(dplyr)

result <- tests %>%
  # 按患者ID分组,直接计算当前患者的检测时间区间端点
  group_by(id) %>%
  mutate(
    first_test = min(test_date),
    last_test = max(test_date)
  ) %>%
  ungroup() %>%
  # 关联对应患者的用药日期
  left_join(meds, by = "id") %>%
  # 区间判断,用药日期非空且落在两次检测之间则返回TRUE
  mutate(
    received_med_within = !is.na(med_date) & med_date > first_test & med_date < last_test,
    # 删除中间计算用的辅助列
    first_test = NULL,
    last_test = NULL
  )

运行代码得到的结果和预期输出完全一致。
该方法全程在长表结构下操作,不会受数据集其他字段的影响,逻辑简单易维护。如果后续场景扩展为患者存在多次检测记录,该逻辑依然有效:默认判断用药时间是否落在该患者最早、最晚检测日期的区间内;如果需要判断用药是否落在相邻两次检测的区间,只需在分组后对检测日期排序,用lag()/lead()函数取相邻日期构造区间即可,灵活度远高于长宽表转换的方案。

注:如果需要包含区间端点(即用药日期等于检测日期也算在间隔内),只要把判断条件里的>/<替换为>=/<=即可。

内容的提问来源于stack exchange,提问作者Andrea M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 13:51:28