R语言:按分组ID统一除唯一ID外的字段值并清理数据
解决方案
针对你的需求,我们可以通过分组统计基准值的方式,识别并替换分组内不一致的行,同时处理缺失值。下面提供dplyr(常规数据量)和data.table(大数据量)两种实现方式:
方法一:使用dplyr(适合常规数据规模)
步骤1:定义分组基准值提取函数
这里选择**众数(分组内出现次数最多的非缺失值)**作为统一值,你可以根据需求调整逻辑:
get_mode <- function(x) { # 过滤缺失值 x_clean <- x[!is.na(x)] # 若组内全为NA则返回NA if (length(x_clean) == 0) return(NA) # 计算各值出现次数,返回次数最多的 unique_vals <- unique(x_clean) unique_vals[which.max(tabulate(match(x_clean, unique_vals)))] }
步骤2:识别不一致行并替换
library(dplyr) # 加载原始数据 df <- data.frame(id = c(1:10), title = c("abc", "aac", "abc", "def", "def", "dde", "ghi", NA, "jkl", "mno"), id2 = c(1,1,1,2,2,2,3,4,4,5)) # 分组标记不一致行并生成基准值 df_processed <- df %>% group_by(id2) %>% mutate( group_title = get_mode(title), # 生成分组统一的title # 标记需要修正的行:缺失值或与基准值不符的行 is_inconsistent = is.na(title) | (title != group_title) ) %>% ungroup() # 替换得到目标数据框df2 df2 <- df_processed %>% mutate(title = group_title) %>% select(-group_title, -is_inconsistent) # 删除辅助列
方法二:使用data.table(适合大数据量)
如果你的数据量级很大,data.table的分组运算效率会更高:
library(data.table) # 转换为data.table格式 setDT(df) # 复用众数函数 get_mode <- function(x) { x_clean <- x[!is.na(x)] if (length(x_clean) == 0) return(NA) unique_vals <- unique(x_clean) unique_vals[which.max(tabulate(match(x_clean, unique_vals)))] } # 分组计算基准值、标记不一致行并替换 df[, group_title := get_mode(title), by = id2] df[, is_inconsistent := is.na(title) | (title != group_title)] df2 <- df[, .(id, title = group_title, id2)]
自定义基准值逻辑
如果分组内没有明确的众数(多个值出现次数相同),可以替换基准值的选择逻辑:
- 取分组内第一个非缺失值:
get_first_non_na <- function(x) { x[!is.na(x)][1] } - 取分组内字典序最小的非缺失值:
get_min_val <- function(x) { x_clean <- x[!is.na(x)] if (length(x_clean) == 0) return(NA) min(x_clean) }
将上述函数替换代码中的get_mode即可适配不同需求。
内容的提问来源于stack exchange,提问作者H.Stevens
相关产品推荐
相关产品推荐

