R语言数据框按指定列去重:最后一列不同则保留对应行
R语言按规则实现数据框去重方案
规则明确
先把需求的判定逻辑理清楚,避免代码逻辑偏差:
- 先选定用于判定重复的基准列(示例中为车型、生产年份、总价三列),这些列取值完全一致的行归为同一重复候选组
- 对每个候选组检查最后一列
time_stamp的取值:- 如果组内
time_stamp存在不同取值,组内所有行全部保留,不做删除 - 如果组内
time_stamp取值完全一致,仅保留组内1行,删除其余重复行
- 如果组内
实现方法
方法1:dplyr 实现(代码可读性高,推荐日常分析用)
加载dplyr包即可运行,只需要调整dup_check_cols里的列名就能适配自己的数据集:
library(dplyr) # 在这里修改你需要用来判定重复的基准列名 dup_check_cols <- c("vehicle_type", "year_of_manufacture", "price_total") cars_dedup <- cars %>% group_by(across(all_of(dup_check_cols))) %>% # 统计每个基准组内time_stamp的唯一值数量 mutate(ts_unique_cnt = n_distinct(time_stamp)) %>% # 按基准列+time_stamp二次分组 group_by(across(c(all_of(dup_check_cols), time_stamp)), .add = FALSE) %>% # 组内时间戳有差异就全留,否则只留第一行 filter(if (first(ts_unique_cnt) > 1) TRUE else row_number() == 1) %>% ungroup() %>% # 删掉中间生成的统计列 select(-ts_unique_cnt)
如果需要保留重复组的最后一行而不是第一行,把row_number() == 1改成row_number() == n()即可。
方法2:Base R 原生实现(无需安装第三方包)
不需要依赖任何扩展包,纯原生R函数就能实现,逻辑和上面完全一致:
# 在这里修改你需要用来判定重复的基准列名 dup_check_cols <- c("vehicle_type", "year_of_manufacture", "price_total") # 生成基准列分组标识 base_group_key <- do.call(paste, c(cars[dup_check_cols], sep = "##|##")) # 统计每个基准组内time_stamp的唯一值数量 ts_unique_cnt <- ave(as.character(cars$time_stamp), base_group_key, FUN = function(x) length(unique(x))) # 生成基准列+time_stamp的完整分组标识 full_group_key <- paste(base_group_key, cars$time_stamp, sep = "##|##") # 按规则筛选行 cars_dedup <- cars[as.numeric(ts_unique_cnt) > 1 | !duplicated(full_group_key), ]
如果要保留重复组最后一行,把!duplicated(full_group_key)改成!duplicated(full_group_key, fromLast = TRUE)就行。
注意事项
你提供的示例构造代码存在小问题:time_stamp向量长度为4,和其余列的长度5不匹配,运行时R会自动循环补齐,实际使用时请保证所有列长度一致,避免数据错乱。
内容的提问来源于stack exchange,提问作者Sofie Zippay
相关产品推荐
相关产品推荐

