基于数据集属性为物种分配所属科的技术实现求助
解决方案
你的数据是典型的树形层级结构(科→属→种),可以用dplyr结合递归查询高效追溯每个节点的科归属,以下是两种实用方法:
方法1:用tidyr::unfold逐层关联(适合大数据)
先提取科的ID与名称映射,再递归展开父节点直到匹配到科:
library(dplyr) library(tidyr) # 构建科ID到名称的映射(转小写匹配预期输出) family_map <- dat %>% filter(rank == "family") %>% select(family_id = ID, family = scientificName) %>% mutate(family = tolower(family)) # 递归展开父节点并匹配科信息 dat_with_family <- dat %>% mutate(current_id = ID) %>% # 逐层向上展开父节点 unfold(parentID, .init = current_id) %>% left_join(family_map, by = c("parentID" = "family_id")) %>% # 保留每个原始ID对应的首个有效科信息 group_by(ID) %>% filter(!is.na(family)) %>% slice_head(n = 1) %>% ungroup() %>% # 合并回原始数据 right_join(dat, by = "ID") %>% select(ID, parentID, rank, scientificName, family)
方法2:递归函数直接查询(代码更简洁)
用purrr的递归函数对每个ID向上追溯,直到找到科层级:
library(dplyr) library(purrr) # 定义递归查询函数 get_family <- function(id) { node <- dat %>% filter(ID == id) if (node$rank == "family") { return(tolower(node$scientificName)) } else { get_family(node$parentID) } } # 给每行添加family列 dat$family <- map_chr(dat$ID, get_family)
验证结果
两种方法最终生成的family列都与你预期一致:
print(dat$family) # 输出: [1] "fama" "famb" "fama" "fama" "famb" "famb" "fama" "fama" "fama" "famb" "famb" "famb"
内容的提问来源于stack exchange,提问作者Jhonny Guedes
相关产品推荐
相关产品推荐

