如何在R的DataFrame中筛选多列值存在差异的行
筛选行内存在差异的记录
数据
以下是你提供的数据框片段:
df <- structure(list(ID = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J"), C1 = c("5", "5", "6", "6", "6", "5", "7", "—", "—", "5"), C2 = c("5", "5", "6", "6", "6", "5", "—", "8", "—", "5"), C3 = c("5", "5", "6", "6", "6", "5", "—", "—", "9", "5"), C4 = c("5", "5", "6", "6", "6", "5", "—", "—", "9", "5")), row.names = c(NA, 10L), class = "data.frame")
对应的表格展示:
| ID | C1 | C2 | C3 | C4 |
|---|---|---|---|---|
| A | 5 | 5 | 5 | 5 |
| B | 5 | 5 | 5 | 5 |
| C | 6 | 6 | 6 | 6 |
| D | 6 | 6 | 6 | 6 |
| E | 6 | 6 | 6 | 6 |
| F | 5 | 5 | 5 | 5 |
| G | 7 | — | — | — |
| H | — | 8 | — | — |
| I | — | — | 9 | 9 |
| J | 5 | 5 | 5 | 5 |
解决方案(dplyr管道实现)
用dplyr可以简洁地实现需求,不需要写循环:
library(dplyr) # 筛选C1-C4列存在差异的行 result <- df %>% # 把占位符“—”转成NA,方便后续处理 mutate(across(C1:C4, ~ na_if(., "—"))) %>% # 切换到按行处理模式 rowwise() %>% # 筛选出非NA值的唯一数量>1的行 filter(n_distinct(c_across(C1:C4), na.rm = TRUE) > 1) %>% # 取消按行分组 ungroup() # 查看结果 print(result)
运行后得到的结果就是你要的第7-9行:
| ID | C1 | C2 | C3 | C4 |
|---|---|---|---|---|
| G | 7 | NA | NA | NA |
| H | NA | 8 | NA | NA |
| I | NA | NA | 9 | 9 |
核心逻辑
na_if(., "—"):把数据里的“—”替换成R标准缺失值NA,避免干扰唯一值计算;rowwise():让后续操作逐行执行,确保每行单独计算唯一值;c_across(C1:C4):一次性选中目标列,n_distinct(na.rm = TRUE)计算每行非缺失值的不同数量,只要数量大于1,就说明该行存在差异;- 最后
ungroup()恢复数据框默认的列处理模式。
内容的提问来源于stack exchange,提问作者ginn
相关产品推荐
相关产品推荐

