如何在R中将分类学宽数据框转换为层次化数据结构?
将宽格式分类计数数据转换为hiervis兼容的层次化格式
针对你的需求,我们可以通过层级计数汇总+行重复的方式,高效将宽格式分类数据转换为hiervis桑基图所需的name-parent结构,同时适配4万+条观测的大样本场景。
核心思路
目标结构的本质是:每个分类节点的重复行数等于其所有下游子节点的计数总和。比如顶层的Animalia重复5次(对应下属Felidae的2条+Canidae的3条),底层的Felidae重复2次(对应原始计数)。我们从最底层到顶层逐级汇总计数,再构建父子关系,最后按计数重复行即可。
完整代码实现
# 加载依赖包 library(dplyr) library(tidyr) library(hiervis) # 1. 定义原始数据(替换为你的真实数据) wide_df <- data.frame( kingdom = c("Animalia", "Animalia", "Plantae", "Plantae"), phylum = c("Chordata", "Chordata", "Angiosperms", "Angiosperms"), class = c("Mammalia", "Mammalia", "Dicotyledons", "Dicotyledons"), order = c("Carnivora", "Carnivora", "Rosales", "Solanales"), family = c("Felidae", "Canidae", "Rosaceae", "Solanaceae"), count = c(2, 3, 1, 4) ) # 2. 指定分类层级顺序(按从顶层到底层的顺序) taxon_levels <- c("kingdom", "phylum", "class", "order", "family") # 3. 逐级计算每个分类节点的总计数 level_counts <- list() for (i in length(taxon_levels):1) { current_level <- taxon_levels[i] if (i == length(taxon_levels)) { # 最底层直接使用原始计数 level_counts[[current_level]] <- wide_df %>% select(all_of(current_level), count) %>% rename(name = all_of(current_level)) } else { # 上层节点的计数 = 所有下属子节点的计数之和 child_level <- taxon_levels[i+1] level_counts[[current_level]] <- wide_df %>% select(all_of(c(taxon_levels[1:i], "count"))) %>% group_by(across(all_of(taxon_levels[1:i]))) %>% summarise(count = sum(count), .groups = "drop") %>% select(all_of(current_level), count) %>% rename(name = all_of(current_level)) %>% distinct() } } # 4. 为每个节点添加父节点信息 hierarchical_list <- list() for (i in 1:length(taxon_levels)) { current_level <- taxon_levels[i] if (i == 1) { # 顶层节点无父节点,设为NA hierarchical_list[[current_level]] <- level_counts[[current_level]] %>% mutate(parent = NA_character_) } else { # 关联当前节点与父节点的对应关系 parent_level <- taxon_levels[i-1] parent_map <- wide_df %>% select(all_of(c(parent_level, current_level))) %>% distinct() hierarchical_list[[current_level]] <- level_counts[[current_level]] %>% left_join(parent_map, by = c("name" = current_level)) %>% rename(parent = all_of(parent_level)) %>% select(name, parent, count) } } # 5. 合并数据并按计数重复行,得到最终格式 hierarchical_df <- bind_rows(hierarchical_list) %>% uncount(count) %>% select(name, parent) # 6. 用hiervis绘制桑基图 hiervis(hierarchical_df, type = "sankey")
关键优势
- 采用向量化操作而非逐行循环,处理4万+条数据时效率更高;
- 自动适配任意数量的分类层级,只需调整
taxon_levels即可; - 去重步骤避免了同一分类节点的重复计算,保证结果准确性。
内容的提问来源于stack exchange,提问作者Bradley Allf
相关产品推荐
相关产品推荐

