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

如何在R语言中找到树状图k分组下每组的最高节点?

如何用dendextend绘制k切割后各簇的最高节点?

我正在使用dendextend包在R语言中处理树状图,希望仅绘制按k值切割树后每个簇中高度最高的节点,想了解是否有便捷的实现方法?

可复现示例

###### sample tree ######

library(dendextend)
library(dplyr)

dend15 <- c(1:5) %>%
  dist() %>%
  hclust(method = "average") %>%
  as.dendrogram()


###### plotting with clusters based on k #######

## 可以通过给set()函数传入NA向量来控制节点是否显示
node_xy <- get_nodes_xy(dend15) ## 获取所有节点的坐标
v <- rep(NA, nrow(node_xy)) ## 初始化与节点数长度一致的向量
v[c(2,5)] <- 19 ## 给节点2和5设置形状19(手动指定的节点)

dend15 <- dend15 %>% set("nodes_pch",v) ## 设置节点形状

dend15 %>% plot(main="sample tree with highest nodes in k")
dend15 %>% rect.dendrogram(k=2) ## 绘制k=2时的簇矩形

切割为k=2的树状图

我希望能针对任意树状图和任意k值,自动确定需要绘制的节点。更宽泛地说,想了解如何结合cutree()和rect.dendrogram()的信息,通过dendextend的数据来控制节点显示。

更新:heights_per_k.dendrogram()函数会返回不同k值切割时的树高,可通过height @ k > node_h > height @ k+1筛选节点,但该方法无法覆盖单叶形成簇的情况(如示例中k=3时的场景)。


解决方案

要解决单叶簇的问题,我们可以通过簇的叶节点追溯所有相关节点,再筛选每个簇的最高节点的方式实现,具体步骤如下:

1. 定义获取各簇最高节点的函数

get_top_cluster_nodes <- function(dend, k) {
  # 获取每个叶节点的簇分配结果
  cluster_assign <- cutree(dend, k = k)
  
  # 获取所有节点的关键信息:节点ID、高度、是否为叶节点
  node_info <- dend %>% 
    get_nodes_attr(c("label", "height", "leaf")) %>%
    mutate(node_id = row_number())
  
  # 遍历每个簇,找出对应最高节点
  top_nodes <- c()
  for (cluster in unique(cluster_assign)) {
    # 当前簇包含的所有叶节点
    cluster_leaves <- names(cluster_assign[cluster_assign == cluster])
    
    # 收集当前簇所有相关节点(叶节点+所有祖先节点)
    cluster_nodes <- c()
    for (leaf in cluster_leaves) {
      # 获取该叶节点的所有祖先节点ID
      ancestor_ids <- dend %>% get_leaf_ancestors(leaf)
      cluster_nodes <- c(cluster_nodes, ancestor_ids, which(node_info$label == leaf))
    }
    cluster_nodes <- unique(cluster_nodes)
    
    # 筛选当前簇的节点,并找出高度最高的那个
    top_node <- node_info[cluster_nodes, ] %>%
      arrange(desc(height)) %>%
      slice(1) %>%
      pull(node_id)
    
    top_nodes <- c(top_nodes, top_node)
  }
  
  return(top_nodes)
}

2. 应用函数并绘图

# 设置目标k值
k <- 3

# 获取各簇最高节点ID
top_nodes <- get_top_cluster_nodes(dend15, k)

# 配置节点显示:仅保留目标节点,其余设为NA
v <- rep(NA, nrow(get_nodes_xy(dend15)))
v[top_nodes] <- 19

# 更新树状图的节点样式
dend15 <- dend15 %>% set("nodes_pch", v)

# 绘制结果
plot(dend15, main = paste0("k=", k, "时仅显示各簇最高节点的树状图"))
rect.dendrogram(dend15, k = k)

方法说明

  • cutree():快速获取每个叶节点的簇归属,明确每个簇包含的叶子
  • get_leaf_ancestors():追溯叶节点的所有祖先节点,确保覆盖整个簇的所有层级节点
  • 按节点高度降序筛选:直接取每个簇中高度最高的节点(单叶簇的最高节点就是叶节点本身,完美覆盖边界场景)
  • 通过set("nodes_pch", v):用NA隐藏不需要显示的节点,仅保留目标节点

内容的提问来源于stack exchange,提问作者perechen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:05:44