如何基于匹配分组生成IndividualID差异列(使用dplyr工具)
高效计算分组内ID差集:dplyr + stringr实现
需求说明
需要在数据集中创建新列IndividualID_Difference,规则如下:
- 分组逻辑:按
Date、Time、SeriesNumber分组,每组包含Context为Mixed和NON_Mixed的行 - 计算规则:
Mixed行的IndividualID_Difference与原IndividualID完全一致NON_Mixed行需移除与同组Mixed行重复的ID,保留唯一部分
- 约束:
IndividualID列表规模庞大,需保证处理效率
原数据示例
Date Time Context SeriesNumber IndividualID 01/01/2000 8.00 Mixed 1 a, b, c, d, e, f 01/01/2000 8.00 NON_Mixed 1 d, e, f, g, h 01/01/2000 9.00 Mixed 2 c, d, e, f 01/01/2000 9.00 NON_Mixed 2 a, b, c, d 01/01/2000 9.00 NON_Mixed 2 e, f, g, h
期望输出
Date Time Context SeriesNumber IndividualID IndividualID_Difference 01/01/2000 8.00 Mixed 1 a, b, c, d, e, f a, b, c, d, e, f 01/01/2000 8.00 NON_Mixed 1 d, e, f, g, h g, h 01/01/2000 9.00 Mixed 2 c, d, e, f c, d, e, f 01/01/2000 9.00 NON_Mixed 2 a, b, c, d a, b 01/01/2000 9.00 NON_Mixed 2 e, f, g, h g, h
解决方案代码
library(dplyr) library(stringr) # 假设原数据框为df df_processed <- df %>% group_by(Date, Time, SeriesNumber) %>% # 提取每组Mixed行的ID并转为字符向量(仅保留第一个Mixed行,确保每组唯一) mutate(mixed_id_vec = str_split(IndividualID[Context == "Mixed"][1], ",\\s+")[[1]]) %>% mutate(IndividualID_Difference = case_when( # Mixed行直接复用原ID Context == "Mixed" ~ IndividualID, # NON_Mixed行计算与Mixed ID的差集,再合并为字符串 TRUE ~ { current_id_vec <- str_split(IndividualID, ",\\s+")[[1]] diff_ids <- setdiff(current_id_vec, mixed_id_vec) str_c(diff_ids, collapse = ", ") } )) %>% # 移除临时辅助列 select(-mixed_id_vec) %>% ungroup()
效率说明
- 摒弃
grepl逐个匹配的低效方式,改用向量级集合操作setdiff,处理大规模ID列表时性能更优 - 分组内仅提取一次Mixed行的ID向量,减少重复计算
内容的提问来源于stack exchange,提问作者MIGUEL
相关产品推荐
相关产品推荐

