基于dplyr实现按ID筛选最早含指定结果的同日期数据
多变量数据集的日期筛选解决方案
需求说明
处理包含IDrow(唯一ID)、date(采样日期)、result(采样结果:NP1、NP2、NP3)的数据集,需为每个IDrow筛选出最早的满足以下条件的日期:
- 该日期下至少同时存在NP1和NP2;
- 若存在同时包含NP1、NP2、NP3的日期,优先选择这类日期中的最早者。
原始数据集
# 构造原始数据 df <- data.frame( IDrow = c("ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID2", "ID2", "ID2", "ID3", "ID3", "ID3"), date = c("01-01-09", "01-01-10", "01-01-10", "01-01-10", "03-03-15", "03-03-15", "03-03-15", "01-05-10", "01-05-10", "01-05-10", "02-08-11", "02-08-11", "02-08-11"), result = c("NP1", "NP1", "NP2", "NP3", "NP1", "NP2", "NP3", "NP1", "NP2", "NP3", "NP1", "NP2", "NP3") )
错误尝试分析
- 仅按
IDrow分组取最早日期:会遗漏后续日期的多结果行,因为NP1的单独早日期不满足同时存在NP2的条件。 - 按
IDrow+result分组取最早日期:会保留NP1的单独早日期(如ID1的01-01-09),不符合“日期需同时包含NP1和NP2”的核心要求。
正确解决方案(dplyr实现)
library(dplyr) # 先将字符型日期转换为日期格式,确保排序逻辑正确 df$date <- as.Date(df$date, format = "%d-%m-%y") df_processed <- df %>% # 按ID和日期分组,统计该日期下的结果覆盖情况 group_by(IDrow, date) %>% mutate( has_NP1 = any(result == "NP1"), has_NP2 = any(result == "NP2"), has_NP3 = any(result == "NP3"), # 标记日期是否符合基础条件:同时有NP1和NP2 meets_criteria = has_NP1 & has_NP2, # 定义优先级:同时有三个结果的日期优先级最高(1),仅满足基础条件的为2 priority = ifelse(meets_criteria & has_NP3, 1, ifelse(meets_criteria, 2, 3)) ) %>% ungroup() %>% # 过滤掉不符合条件的日期 filter(meets_criteria) %>% # 按ID分组,先选优先级最高的日期类别,再在该类别中选最早的日期 group_by(IDrow) %>% slice_min(order_by = priority, with_ties = FALSE) %>% slice_min(order_by = date, with_ties = FALSE) %>% # 保留原始行结构并整理输出顺序 select(IDrow, date, result) %>% arrange(IDrow, result) %>% ungroup() # 转换回原日期格式展示(可选操作) df_processed$date <- format(df_processed$date, "%d-%m-%y") print(df_processed)
代码逻辑解释
- 日期格式转换:将字符型
date转为标准日期类型,避免字符串排序的逻辑错误。 - 分组统计结果覆盖:按
IDrow+date分组,标记每个日期是否包含目标结果,并定义优先级规则。 - 筛选有效日期:过滤掉不满足“同时存在NP1和NP2”的无效日期。
- 锁定目标日期:按
IDrow分组,先筛选优先级最高的日期类别,再在该类别中选取最早的日期。 - 整理输出结构:保留原始的“每个结果一行”结构,按ID和结果排序后输出。
最终输出结果
IDrow date result <chr> <chr> <chr> 1 ID1 01-01-10 NP1 2 ID1 01-01-10 NP2 3 ID1 01-01-10 NP3 4 ID2 01-05-10 NP1 5 ID2 01-05-10 NP2 6 ID2 01-05-10 NP3 7 ID3 02-08-11 NP1 8 ID3 02-08-11 NP2 9 ID3 02-08-11 NP3
内容的提问来源于stack exchange,提问作者SorenRand
相关产品推荐
相关产品推荐

