R语言使用dplyr的filter/subset筛选列值恰好出现2次的行问题
按列值出现频次筛选行的实现方案
原有代码问题说明
- 第一段dplyr代码:核心分组计数的逻辑方向正确,有两个常见问题:一是额外用
mutate生成计数列属于冗余步骤,二是如果同时加载了plyr等其他带同名函数的包,可能出现函数冲突导致分组计数失效;另外筛选后没有解除分组,可能影响后续对结果数据框的操作。 - 第二段subset代码:逻辑本身不满足需求:
duplicated(x)仅会标记重复取值中非首次出现的行,既会漏掉每个重复取值第一次出现的记录,也无法区分取值的出现次数,会把出现3次及以上的取值的重复行也保留下来。
正确实现代码
dplyr::filter 实现
不需要额外生成计数列,直接在分组内判断组内行数即可,筛选后记得解除分组:
library(dplyr) df2 <- df %>% group_by(x) %>% filter(n() == 2) %>% ungroup()
如果存在多包函数冲突的问题,可以显式指定dplyr的函数调用,避免函数覆盖导致的异常:
df2 <- df %>% dplyr::group_by(x) %>% dplyr::filter(dplyr::n() == 2) %>% dplyr::ungroup()
base::subset 实现
先统计目标列的取值频次,提取出恰好出现2次的取值,再匹配筛选对应行:
# 统计x列各取值的出现次数 val_count <- table(df$x) # 提取出现次数恰好为2的取值 target_val <- names(val_count[val_count == 2]) # 筛选对应行 df2 <- subset(df, x %in% target_val)
结果校验
运行以下代码,若返回TRUE则说明筛选结果符合预期:
all(table(df2$x) == 2)
内容的提问来源于stack exchange,提问作者user19409573
相关产品推荐
相关产品推荐

