如何在根节点合并多个hclust对象或树状图?附USArrests聚类示例
当然有办法啦!要把多个hclust对象在根节点合并,核心思路是先把hclust转换成系统发育树格式(比如phylo对象),然后合并这些树,最后再转回hclust或者直接用于热图展示。下面结合你的USArrests数据集示例一步步来:
方法步骤与示例代码
1. 准备数据与地区划分
先补全完整的美国地区划分,给数据集添加地区标签:
# 加载必要工具包 library(ape) library(pheatmap) library(dplyr) # 完整的美国四大州地区划分 Northeast <- c("Connecticut", "Maine", "Massachusetts", "New Hampshire", "Rhode Island", "Vermont", "New Jersey", "New York", "Pennsylvania") Midwest <- c("Illinois", "Indiana", "Michigan", "Ohio", "Wisconsin", "Iowa", "Kansas", "Minnesota", "Missouri", "Nebraska", "North Dakota", "South Dakota") South <- c("Delaware", "Florida", "Georgia", "Maryland", "North Carolina", "South Carolina", "Virginia", "West Virginia", "Alabama", "Kentucky", "Mississippi", "Tennessee", "Arkansas", "Louisiana", "Oklahoma", "Texas") West <- c("Arizona", "Colorado", "Idaho", "Montana", "Nevada", "New Mexico", "Utah", "Wyoming", "Alaska", "California", "Hawaii", "Oregon", "Washington") # 给USArrests添加地区列 USArrests_regions <- USArrests %>% mutate(Region = case_when( rownames(.) %in% Northeast ~ "Northeast", rownames(.) %in% Midwest ~ "Midwest", rownames(.) %in% South ~ "South", rownames(.) %in% West ~ "West" ))
2. 按地区分别做层次聚类
对每个地区的子集单独计算聚类,得到各自的hclust对象:
# 按地区拆分数据集并逐个聚类 cluster_list <- USArrests_regions %>% group_split(Region) %>% lapply(function(df) { # 提取数值型数据并标准化 scaled_data <- scale(df %>% select(-Region)) # 计算距离矩阵并执行层次聚类 dist_mat <- dist(scaled_data) hclust(dist_mat, method = "ward.D2") }) # 给聚类列表命名,方便后续识别 names(cluster_list) <- c("Northeast", "Midwest", "South", "West")
3. 在根节点合并多个hclust对象
原生hclust结构不支持直接合并,我们先转成phylo树格式,再用bind.tree在根节点合并:
# 将每个hclust对象转换为phylo系统发育树 phylo_list <- lapply(cluster_list, as.phylo) # 初始化合并树为第一个地区的树,然后依次合并剩余树到根节点 merged_tree <- phylo_list[[1]] for (i in 2:length(phylo_list)) { # position=0 表示在根节点处合并 merged_tree <- bind.tree(merged_tree, phylo_list[[i]], position = 0) } # 如果需要转回hclust格式(比如给pheatmap用),直接用as.hclust转换 merged_hclust <- as.hclust(merged_tree)
4. 用合并后的聚类树绘制热图
现在可以把合并后的树作为行聚类规则,搭配地区注释绘制热图:
# 准备行注释数据(标注每个州所属地区) annotation_row <- USArrests_regions %>% select(Region) rownames(annotation_row) <- rownames(USArrests_regions) # 绘制热图,指定行聚类为合并后的hclust对象 pheatmap(scale(USArrests), cluster_rows = merged_hclust, # 使用合并后的聚类树 annotation_row = annotation_row, main = "USArrests Clustered by Region (Merged at Root)", treeheight_row = 60)
关键细节说明
- 为什么要转phylo格式?因为原生hclust的结构只记录单棵树的聚类路径,不支持多树合并操作;而phylo是专门用于树结构的格式,支持灵活的树拼接。
bind.tree的position=0是核心参数,确保每个地区的聚类树都作为合并后大树的一级分支,完美实现根节点合并的需求。
内容的提问来源于stack exchange,提问作者csgroen
相关产品推荐
相关产品推荐

