R语言左连接后按规则筛选重复匹配结果的实现方法
解决方案
针对你的需求,我们可以通过分组分析每个物种名称的匹配情况,结合规则筛选符合要求的记录。以下是修正后的代码:
library(dplyr) # 原始数据定义 plant_data <- data.frame(scientific_name = c("CAREX FOENEA", "CAREX SICCATA", "CAREX FOENEA", "ABIES BIFOLIA", "ABIES MENZIESII", "CAREX ECHINATA", "CAREX MURICATA", "CAREX ANGUSTIOR", "CAREX MURICATA"), name_origin = c("scientific_name", "scientific_name", "synonym", "scientific_name", "synonym", "scientific_name", "synonym", "scientific_name", "synonym"), id = c(1, 2, 2, 3, 3, 4, 4, 5, 5)) plant_names <- data.frame(scientific_name = c("CAREX FOENEA", "CAREX FOENEA", "ABIES MENZIESII", "ABIES MENZIESII", "CAREX MURICATA")) # 执行左连接 joined_df <- left_join(plant_names, plant_data, by = "scientific_name") # 按规则清洗数据 cleaned_df <- joined_df %>% group_by(scientific_name) %>% mutate( # 标记当前物种是否存在主名记录 has_scientific_name = any(name_origin == "scientific_name"), # 统计当前物种对应的唯一ID数量 unique_id_count = n_distinct(id) ) %>% filter( # 规则1:存在主名时,仅保留主名记录 (has_scientific_name & name_origin == "scientific_name") | # 规则2+3:无主名时,仅当所有匹配记录对应同一ID时保留(同时保留原plant_names的重复) (!has_scientific_name & unique_id_count == 1) ) %>% ungroup() %>% # 移除临时计算的列 select(-has_scientific_name, -unique_id_count) # 查看结果 print(cleaned_df)
代码说明
- 分组标记关键信息:按物种名称分组后,我们标记两个关键指标:
has_scientific_name:该物种是否存在主名记录unique_id_count:该物种对应的唯一ID数量
- 规则筛选:
- 若存在主名,只保留主名类型的记录(满足规则1)
- 若不存在主名,仅当所有匹配记录对应同一个ID时保留(满足规则2:多ID异名全部删除;规则3:原plant_names的重复记录保留)
运行结果
# A tibble: 4 × 3 scientific_name name_origin id <chr> <chr> <dbl> 1 CAREX FOENEA scientific_name 1 2 CAREX FOENEA scientific_name 1 3 ABIES MENZIESII synonym 3 4 ABIES MENZIESII synonym 3
内容的提问来源于stack exchange,提问作者ifoxfoot
相关产品推荐
相关产品推荐

