如何判断数据框同组内是否存在互为同义词的物种
修正dplyr代码实现物种同义词组内标记需求
示例数据
首先定义可复现的输入数据框:
df <- data.frame( species = c("Species X","Species A", "Species Z", "Species A", "Species B", "Species C", "Species C", "Species D", "Species D", "Species A", "Species B", "Species E","Species Y","Species W","Species R"), synonyms = c("Species Y","Species B", "no_synonym", "Species B", "Species A", "Species E", "Species E", "no_synonym", "no_synonym", "Species B", "Species A", "Species C","Species X","Species R","Species W"), groups = c("G1","G1", "G1", "G1", "G1", "G2", "G2", "G3", "G3", "G1", "G4", "G5","G6","G7","G8") )
需求说明
新增列at_least_two_synonyms_in_group,规则为:
- 标记为yes:当前行的物种所在分组中,存在与它互为同义词的另一物种(即A的同义词是B,且B的同义词是A,且A、B都在同一分组内)
- 标记为no:其他情况(无同义词、同义词不在同组、仅单向同义词匹配等)
原代码问题
原代码的核心问题是给整个分组统一标记,没有区分组内不同物种的匹配情况,导致像G1组的Species X、Species Z这类不符合条件的物种也被错误标记。
修正后的代码
library(dplyr) df <- df %>% group_by(groups) %>% mutate( # 获取当前组内的所有唯一物种集合 group_species = list(unique(species)), # 构建组内有效同义词对(排除no_synonym) synonym_pairs = list(filter(cur_data(), synonyms != "no_synonym") %>% select(species, synonyms)), # 判断当前物种是否属于组内双向同义词对 is_mutual_synonym = case_when( synonyms == "no_synonym" ~ FALSE, # 先检查同义词在组内,再验证该同义词的同义词包含当前物种 synonyms %in% unlist(group_species) ~ any(filter(unlist(synonym_pairs, recursive = FALSE), species == synonyms)$synonyms == species), TRUE ~ FALSE ), # 生成最终标记列 at_least_two_synonyms_in_group = ifelse(is_mutual_synonym, "yes", "no") ) %>% # 清理中间辅助列 select(-group_species, -synonym_pairs, -is_mutual_synonym) %>% ungroup()
代码逻辑说明
- 按分组聚合后,先获取当前组内的所有唯一物种集合,用于快速判断同义词是否在组内
- 构建组内的有效同义词对(排除
no_synonym),用于双向匹配验证 - 逐行判断:
- 若同义词为
no_synonym,直接判定为不符合条件 - 否则先确认同义词在当前组的物种中,再验证该同义词的同义词列表里包含当前物种(确保双向互为同义词)
- 若同义词为
- 根据判断结果生成"yes"/"no"标记,并清理中间辅助列
运行后即可得到符合预期的输出结果。
内容的提问来源于stack exchange,提问作者tadeufontes
相关产品推荐
相关产品推荐

