R语言DataFrame去重:保留含有效信息的重复行
解决R DataFrame中重复ID行保留有效信息的问题
问题背景
给定的R DataFrame结构如下:
id <- c("3235453", "3235453", "21354315", "21354315", "2121421") Plan_name<- c("angers", "strasbourg", "Benzema", "angers", "montpellier") service_line<- c("", "AMRS", "", "Therapy", "") treatment<-c("", "MH", "", "MH", "") df <- data.frame (id, Plan_name, treatment, service_line)
该DataFrame存在重复ID行,需求是保留每个ID对应的treatment和service_line列包含有效非空信息的行。使用df[duplicated(df[,c(1,3)]),]时返回空DataFrame,需要修正方案。
问题原因
你用的duplicated(df[,c(1,3)])是检查id和treatment的组合重复情况,但你的数据中,同一ID的两行treatment一列是空、一列有值(比如ID"3235453"的treatment分别为""和"MH"),这两列组合并不重复,因此duplicated返回全FALSE,最终得到空结果。
解决方法
方法1:使用dplyr包(推荐)
通过给每行计算有效信息得分(统计treatment和service_line非空的数量),按ID分组保留得分最高的行:
library(dplyr) df_cleaned <- df %>% # 计算每行有效信息数量:非空计1,空计0 mutate(score = as.integer(treatment != "") + as.integer(service_line != "")) %>% group_by(id) %>% # 保留得分最高的行;若得分相同(如都为0),保留第一行 slice_max(score, with_ties = FALSE) %>% select(-score) %>% ungroup() print(df_cleaned)
运行结果:
# A tibble: 3 × 4 id Plan_name treatment service_line <chr> <chr> <chr> <chr> 1 2121421 montpellier "" "" 2 21354315 angers MH Therapy 3 3235453 strasbourg MH AMRS
方法2:使用Base R
同样先计算有效信息得分,再按ID筛选目标行:
# 添加得分列 df$score <- as.integer(df$treatment != "") + as.integer(df$service_line != "") # 按ID分组,获取每组得分最高的行索引 max_score_indices <- tapply(seq_len(nrow(df)), df$id, function(x) { x[which.max(df$score[x])] }) # 提取目标行并移除临时得分列 df_cleaned <- df[unlist(max_score_indices), !names(df) %in% "score"] print(df_cleaned)
结果与方法1一致。
补充说明
若同一ID下存在多行有效信息得分相同的情况(比如两行的treatment和service_line都为空),上述方法会保留每组的第一行。如果需要保留所有得分相同的行,只需将slice_max中的with_ties = FALSE改为with_ties = TRUE,或在Base R方法中调整索引筛选逻辑。
内容的提问来源于stack exchange,提问作者samrdbar
相关产品推荐
相关产品推荐

