在单个R数据框中高效识别重复行及标记差异列的方法
高效处理重复org_id的全列重复判断与差异列识别
针对你的20万行混合数据集,以下是基于dplyr和tidyr的优化方案,替代原有的字符串拼接与循环逻辑,更高效且易维护:
优化代码实现
library(dplyr) library(tidyr) # 示例数据(你的原始数据可直接替换此处的df) df <- data.frame(org_id=c("a","a","b","b","b","c"), thing=c("1","1","1","1","2","1"), name=c("really_long_A_name_here", "really_long_A_name_here", "really_long_B_name_here", "really_long_B2_name_here", "really_long_B_name_here", "really_long_C_name_here"), start=c("2020-10-31", "2020-10-31", "2022-09-17", "2022-09-17", "2022-09-17", "2023-05-11") ) # 1. 筛选出所有存在重复的org_id dup_orgs <- df %>% count(org_id) %>% filter(n >= 2) %>% pull(org_id) # 2. 生成核心结果表:判断全列重复、识别差异列 result <- df %>% filter(org_id %in% dup_orgs) %>% group_by(org_id) %>% summarize( # 判断该org_id的所有行是否完全重复 exact_dup = n_distinct(across(everything())) == 1, # 提取存在差异的列名 diff_columns = list(names(select(., -org_id)[sapply(select(., -org_id), n_distinct) > 1])) ) %>% ungroup() %>% # 将差异列列表转为可读字符串,全重复时显示"无" mutate(diff_columns = ifelse(exact_dup, "无", sapply(diff_columns, paste, collapse = ", "))) # 查看结果 print(result) # 可选:查看非全重复org_id的具体差异行(仅保留差异列的值,非差异列设为NA) diff_details <- df %>% filter(org_id %in% result$org_id[!result$exact_dup]) %>% group_by(org_id) %>% mutate(across(-org_id, ~ifelse(n_distinct(.) > 1, as.character(.), NA))) %>% ungroup() print(diff_details)
代码优势
- 效率更高:采用矢量化分组操作,避免循环与字符串拼接,处理20万行数据集的速度远快于原方案。
- 准确性更强:直接基于原始数据类型判断重复,避免字符串拼接可能出现的分隔符冲突、类型转换误差。
- 可读性好:逻辑清晰,通过管道操作串联步骤,便于后续维护与修改。
示例输出
核心结果表
# A tibble: 2 × 3 org_id exact_dup diff_columns <chr> <lgl> <chr> 1 a TRUE 无 2 b FALSE thing, name
差异行详情(可选)
# A tibble: 3 × 4 org_id thing name start <chr> <chr> <chr> <lgl> 1 b 1 really_long_B_name_here NA 2 b 1 really_long_B2_name_here NA 3 b 2 really_long_B_name_here NA
内容的提问来源于stack exchange,提问作者Shawn Janzen
相关产品推荐
相关产品推荐

