如何按ID提取表格数据中的不匹配项?(附R代码尝试)
问题描述
原始输入表格
| ID | info1 | info2 |
|---|---|---|
| A | 01 | 02 |
| A | 11 | 02 |
| B | 01 | 02 |
| B | 10 | 20 |
| C | 03 | 02 |
| C | 01 | 04 |
期望输出表格
需要新增多个mismatch列,展示同一ID下不同行的字段组合:
| ID | info1 | info2 | mismatch1+1 | mismatch 1+2 | mismatch1_2 | mismatch2+1 |
|---|---|---|---|---|---|---|
| A | 01 | 02 | 01:11 | 01:02 | 01:02 | 02:11 |
| A | 11 | 02 | 01:11 | 01:02 | 01:02 | 02:11 |
| B | 01 | 02 | 01:10 | 01:20 | 01:02 | 02:10 |
| B | 10 | 20 | 01:10 | 01:20 | 01:02 | 02:10 |
| C | 03 | 02 | 03:01 | 03:04 | 03:02 | 02:01 |
| C | 01 | 04 | 03:01 | 03:04 | 03:02 | 02:01 |
尝试的代码
t <- t %>% arrange(`ID-COLT`)%>% mutate(across(A1:A2), mismatch_extract_col1_2 = paste(A1[1], A1[2], sep = ":"), mismatch_extract_col1_1 = paste(A1[1], A2[1], sep = ":"), mismatch_extract_col2_2 = paste(A1[1], A2[2], sep = ":"), mismatch_extract_col2_1 = paste(A2[1], A1[2], sep = ":"))
问题分析与解决方案
原代码存在三个核心问题:
- 未按
ID分组,直接取A1[1]等是调用整个数据集的行值,而非同一ID组内的行 - 列名不匹配:原始数据列名为
info1/info2,代码中误用了A1/A2;排序字段ID-COLT与原始列名ID不符 across(A1:A2)语法错误,未指定处理逻辑,属于无效调用
以下是修正后的代码,使用dplyr分组处理实现需求:
library(dplyr) # 假设原始数据框名为df df <- df %>% group_by(ID) %>% mutate( # 提取当前ID组去重排序后的info1/info2值 info1_list = list(sort(unique(info1))), info2_list = list(sort(unique(info2))), # 生成各mismatch列 `mismatch1+1` = paste(info1_list[[1]], collapse = ":"), `mismatch 1+2` = paste(info1, setdiff(info2_list[[1]], info2), sep = ":"), mismatch1_2 = paste(info1, info2, sep = ":"), `mismatch2+1` = paste(info2, setdiff(info1_list[[1]], info1), sep = ":") ) %>% # 移除临时辅助列 select(-info1_list, -info2_list) %>% ungroup()
代码说明
group_by(ID):确保所有操作仅在同一ID的行组内执行setdiff():从组内字段集合中排除当前行的字段值,得到同组另一行的对应值- 所有拼接逻辑均基于当前ID组内的字段,确保结果符合预期
内容的提问来源于stack exchange,提问作者simon brocard
相关产品推荐
相关产品推荐

