You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于其他列信息填充分类学数据列并清理冗余行?

解决分类学层级数据的填充与去重问题

需求说明

需要将分散存储的分类学层级数据(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

步骤解释

  1. 标记分组:cumsum(!is.na(species))会为每个物种(包括其下所有亚种)分配唯一的分组ID,确保不同物种的填充操作独立进行。
  2. 组内填充:在每个分组内向下填充Family、Genus、Species,保证亚种行能继承所属物种的完整分类信息。
  3. 过滤有效行:移除没有物种或亚种的冗余行,只保留有实际分类单元的记录。
  4. 清理数据:删除临时的分组ID列,得到整洁的最终数据。

内容的提问来源于stack exchange,提问作者ar.caravaggi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:53:27