在R语言中按组统计单元格重复值并忽略空白单元格(特殊情况除外)
解决方案
核心逻辑
针对每组的空白/非空白混合场景,分两种规则统计唯一值数量:
- 组内存在非空白单元格时,仅统计非空白值的唯一数量
- 组内全为空白单元格时,将空白视为1个唯一值
基于这个逻辑,我们可以用dplyr高效处理单/多列、多个数据框的场景。
依赖包加载
首先加载dplyr(未安装先运行install.packages("dplyr")):
library(dplyr)
单列处理示例
针对你提供的test数据框,按group分组计算唯一值数量,并判断是否存在非重复值:
test %>% group_by(group) %>% summarise( # 按规则计算唯一值数量 unique_count = case_when( any(value1 != "") ~ n_distinct(value1[value1 != ""]), TRUE ~ 1 ), # 统计组内总条目数 total_count = n() ) %>% # 判断组内是否存在非重复值(唯一数≠总条目数则存在) mutate(has_non_duplicate = unique_count != total_count)
运行结果:
| group | unique_count | total_count | has_non_duplicate |
|---|---|---|---|
| A | 2 | 3 | TRUE |
| B | 1 | 3 | FALSE |
| C | 1 | 3 | FALSE |
多列/多数据框批量处理
如果有大量列或多个数据框需要处理,封装成可复用的函数:
calc_unique_per_group <- function(df, group_col, value_cols) { df %>% group_by({{ group_col }}) %>% summarise( # 批量处理指定值列,计算唯一值数量 across(all_of(value_cols), ~ case_when( any(.x != "") ~ n_distinct(.x[.x != ""]), TRUE ~ 1 ), .names = "{.col}_unique"), total_count = n() ) %>% # 批量判断各列是否存在非重复值 mutate( across(ends_with("_unique"), ~ .x != total_count, .names = "{str_remove(.col, '_unique')}_has_non_duplicate") ) } # 调用示例:处理test数据框的group列与value1列 calc_unique_per_group(test, group, "value1") # 多列处理示例:假设数据框有value1、value2两列 # calc_unique_per_group(your_df, group, c("value1", "value2"))
组内去重(仅保留一行)
如果确认组内全为重复值(unique_count == total_count),可以直接按组去重,保留每组第一行:
test %>% group_by(group) %>% slice(1) %>% ungroup()
如果需要仅保留无重复的组,可结合统计结果筛选:
# 先筛选出无重复的组 valid_groups <- test %>% group_by(group) %>% summarise( unique_count = case_when( any(value1 != "") ~ n_distinct(value1[value1 != ""]), TRUE ~ 1 ), total_count = n() ) %>% filter(unique_count == total_count) %>% pull(group) # 仅保留有效组并去重 test %>% filter(group %in% valid_groups) %>% group_by(group) %>% slice(1) %>% ungroup()
注意事项
- 如果你的空白值是
NA而非空字符串,将代码中的value1 != ""替换为!is.na(value1)即可 slice(1)可替换为slice_sample(n=1)随机保留一行,根据需求调整
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

