如何用R工具解决NatureServe与GBIF分类学1:1异名匹配问题
解决GBIF与NatureServe分类异名的1:1自动匹配问题
核心方案思路
针对1:1属级/种级异名场景,通过NatureServe获取完整分类单元概念(含接受名、异名列表),再对接GBIF的分类数据完成映射,避开合并/拆分的复杂情况。以下是具体实现步骤:
1. 从NatureServe提取完整分类概念信息
natserv::ns_search_spp()仅做模糊搜索,无法返回完整分类单元细节。需先通过搜索获取物种ID,再用natserv::ns_spp()调取包含conceptName、异名列表的完整数据:
# 示例:处理Argynnis aphrodite(对应GBIF的Speyeria aphrodite) # 1. 模糊搜索获取NatureServe物种ID argynnis_search <- natserv::ns_search_spp("Argynnis aphrodite") argynnis_id <- argynnis_search$id[1] # 取第一个匹配结果(需手动验证准确性) # 2. 获取完整分类单元详情 argynnis_details <- natserv::ns_spp(argynnis_id) # 查看关键字段 argynnis_details$conceptName # NatureServe的接受名 argynnis_details$synonyms # 该物种的所有异名(含Speyeria aphrodite)
2. 对接GBIF验证异名映射
用NatureServe返回的异名/接受名,调用rgbif::name_backbone_verbose()匹配GBIF的分类系统:
# 用NatureServe的异名查询GBIF的接受名 gbif_match <- rgbif::name_backbone_verbose("Speyeria aphrodite") gbif_match$acceptedScientificName # GBIF的接受名 gbif_match$genus # 确认属级分类
3. 处理conceptName中隐藏接受名的特殊情况(如Tecmessa scitiscripta)
对于NatureServe仅在conceptName中显示ITIS接受属的物种,直接提取该字段作为接受名,再对接ITIS和GBIF:
# 示例:处理Tecmessa scitiscripta tecmessa_search <- natserv::ns_search_spp("Tecmessa scitiscripta") tecmessa_id <- tecmessa_search$id[1] tecmessa_details <- natserv::ns_spp(tecmessa_id) # 提取NatureServe认可的接受名(含ITIS接受属Cerura) accepted_name <- tecmessa_details$conceptName # 验证ITIS分类 itis_match <- taxize::get_ids(accepted_name, db = "itis") taxize::classification(itis_match$itis, db = "itis") # 对接GBIF验证 gbif_tecmessa <- rgbif::name_backbone_verbose(accepted_name)
4. 封装自动化匹配函数
将流程封装为函数,批量处理1:1异名映射,自动过滤非1:1场景:
match_natserv_gbif <- function(species_name, filter_1to1 = TRUE) { # 1. 定位NatureServe物种ID ns_search <- natserv::ns_search_spp(species_name) if (nrow(ns_search) == 0) { warning(paste("No NatureServe match for:", species_name)) return(NULL) } ns_id <- ns_search$id[1] ns_details <- natserv::ns_spp(ns_id) # 2. 整理分类信息 ns_data <- list( accepted_name = ns_details$conceptName, synonyms = ns_details$synonyms ) # 3. 匹配GBIF数据 gbif_accepted <- rgbif::name_backbone_verbose(ns_data$accepted_name)$acceptedScientificName gbif_syn_matches <- lapply(ns_data$synonyms, function(syn) { res <- rgbif::name_backbone_verbose(syn) res$acceptedScientificName }) names(gbif_syn_matches) <- ns_data$synonyms # 4. 过滤1:1异名场景(可选) if (filter_1to1) { # 仅保留接受名与异名一一对应,且GBIF接受名一致的情况 valid_matches <- Filter(function(x) x == gbif_accepted, gbif_syn_matches) if (length(valid_matches) != 1) { warning(paste("Non 1:1 match for:", species_name)) return(NULL) } } # 返回结果 list( natureserve = ns_data, gbif_accepted = gbif_accepted, gbif_synonym_matches = gbif_syn_matches ) } # 测试函数 match_natserv_gbif("Argynnis aphrodite") match_natserv_gbif("Tecmessa scitiscripta")
关键注意事项
- API请求限制:批量处理时加入
Sys.sleep(1)避免触发NatureServe/GBIF的请求频率限制; - 结果验证:自动匹配后需手动抽样验证,确保ID和分类信息的准确性;
- 属级异名批量处理:对于Speyeria/Argynnis这类属级异名,可先获取属的分类ID,再批量调取属下所有物种的异名数据,提升效率。
内容的提问来源于stack exchange,提问作者Michael Roswell
相关产品推荐
相关产品推荐

