如何用R按MRN统计±1天和±2天范围内的检测总数
问题描述
现有如下R数据,部分人员在4年内最多有48条观测记录,需按MRN分组,统计落在数据框中任意Collected日期±1天和±2天内的观测记录数。
原始数据
Name <- c("Doe, John","Doe, John","Doe, John", "Doe, Jane", "Doe, Jane","Doe, Jane", "Doe, Jane") Accession <- c(123, 234, 345, 456, 567, 678, 789) MRN <-c(55555, 55555, 55555, 66666, 66666, 66666, 66666) Collected <-c("2022-01-05", "2022-01-06", "2022-01-07", "2022-01-08", "2022-01-09", "2022-01-20", "2022-01-15") Result <-c("Detected", "Negative", "Detected", "Negative", "Negative", "Negative", "Detected") CV <- data.frame(Name, Accession, MRN, Collected, Result)
数据预览:
Name Accession MRN Collected Result 1 Doe, John 123 55555 2022-01-05 Detected 2 Doe, John 234 55555 2022-01-06 Negative 3 Doe, John 345 55555 2022-01-07 Detected 4 Doe, Jane 456 66666 2022-01-08 Negative 5 Doe, Jane 567 66666 2022-01-09 Negative 6 Doe, Jane 678 66666 2022-01-20 Negative 7 Doe, Jane 789 66666 2022-01-15 Detected
需求说明
按MRN分组,统计每个人员的观测记录中,落在任意一条Collected日期±1天范围内的记录总数,以及落在任意一条Collected日期±2天范围内的记录总数,期望输出格式如下:
Name MRN +/-1天检测数 +/-2天检测数 Doe, John 55555 3 2 Doe, Jane 66666 3 2
解决方案
使用dplyr结合lubridate包处理日期计算与分组统计,步骤如下:
- 加载所需工具包:
library(dplyr) library(lubridate)
- 将
Collected列转换为标准日期格式:
CV <- CV %>% mutate(Collected = ymd(Collected))
- 按MRN和姓名分组,统计符合条件的记录数:
result <- CV %>% group_by(MRN, Name) %>% summarise( `+/-1天检测数` = sum(sapply(Collected, function(x) any(abs(Collected - x) <= 1 & Collected != x))), `+/-2天检测数` = sum(sapply(Collected, function(x) any(abs(Collected - x) <= 2 & Collected != x))), .groups = "drop" ) # 调整列顺序匹配期望格式 result <- result %>% select(Name, MRN, `+/-1天检测数`, `+/-2天检测数`)
- 查看最终结果:
print(result)
运行后输出:
# A tibble: 2 × 4 Name MRN `+/-1天检测数` `+/-2天检测数` <chr> <dbl> <int> <int> 1 Doe, Jane 66666 3 2 2 Doe, John 55555 3 2
代码说明
sapply(Collected, function(x) any(abs(Collected - x) <= 1 & Collected != x)):对每条日期,检查是否存在其他日期在其±1天范围内,返回逻辑向量后用sum统计符合条件的记录数。group_by(MRN, Name):按MRN和姓名分组,确保每个人员的统计独立。.groups = "drop":取消分组状态,返回普通数据框格式。
内容的提问来源于stack exchange,提问作者T.McMillen
相关产品推荐
相关产品推荐

