如何基于其他列信息填充分类学数据列并清理冗余行?
解决分类学层级数据的填充与去重问题
需求说明
需要将分散存储的分类学层级数据(Family、Genus、Species、Subspecies逐行单独出现有效值)处理为每行包含完整分类信息的结构,仅保留有物种(Species)或亚种(Subspecies)的有效行,避免不同分类单元的数据串扰。
示例数据
df <- data.frame( family = c("Rheaidae",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA), genus = c(NA,"Rhea",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA), species = c(NA,NA,"americana",NA,NA,NA,NA,NA,"pennata",NA,NA,NA), subspecies = c(NA,NA,NA,"americana","intermedia","nobilis","araneipes","albescens",NA,"garleppi","tarapacensis","pennata") )
问题分析
之前尝试的fill(everything(), .direction = "downup") %>% distinct_all()会全局填充所有列,导致不同物种的分类信息互相串扰(比如第二个物种pennata会被前一个物种americana的Family/Genus错误覆盖)。核心问题是没有按物种边界进行分组填充。
正确解决方案
通过「标记物种分组→组内填充→过滤有效行」的步骤实现,使用dplyr和tidyr包完成:
library(dplyr) library(tidyr) processed_df <- df %>% # 标记物种分组:每遇到非NA的species,分组ID递增 mutate(group_id = cumsum(!is.na(species))) %>% # 按分组处理,避免跨物种串扰 group_by(group_id) %>% # 组内向下填充Family、Genus、Species列 fill(family, genus, species, .direction = "down") %>% # 只保留有物种或亚种的有效行 filter(!is.na(species) | !is.na(subspecies)) %>% # 取消分组并删除临时分组列 ungroup() %>% select(-group_id) print(processed_df)
处理结果
执行后得到的完整分类数据如下:
family genus species subspecies 1 Rheaidae Rhea americana americana 2 Rheaidae Rhea americana intermedia 3 Rheaidae Rhea americana nobilis 4 Rheaidae Rhea americana araneipes 5 Rheaidae Rhea americana albescens 6 Rheaidae Rhea pennata <NA> 7 Rheaidae Rhea pennata garleppi 8 Rheaidae Rhea pennata tarapacensis 9 Rheaidae Rhea pennata pennata
步骤解释
- 标记分组:
cumsum(!is.na(species))会为每个物种(包括其下所有亚种)分配唯一的分组ID,确保不同物种的填充操作独立进行。 - 组内填充:在每个分组内向下填充Family、Genus、Species,保证亚种行能继承所属物种的完整分类信息。
- 过滤有效行:移除没有物种或亚种的冗余行,只保留有实际分类单元的记录。
- 清理数据:删除临时的分组ID列,得到整洁的最终数据。
内容的提问来源于stack exchange,提问作者ar.caravaggi
相关产品推荐
相关产品推荐

