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

使用R语言dendextend的get_subdendrograms时修改标签致子树为NULL

问题:修改 dendextend 树状图标签后生成子树出现 NULL

我使用 dendextend 包生成子树状图(subdendrograms),未修改叶节点标签时一切正常,但将标签改为'Y'或'B'后,多个子树变为 NULL。

可复现代码

library(dplyr)
library(dendextend)

new_labels <- c("Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", 
                "Y", "B", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")

new_colors <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 
                1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
                8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
                1, 1, 1, 1)

# define dendrogram object to play with:
dend <- iris[, -5] %>%
  dist() %>%
  hclust() %>%
  as.dendrogram() %>%
  # change the color of the labels
  set('labels_colors', new_colors[order.dendrogram(.)]) %>% 
  # change the labels to 'Y' or 'B'
  set('labels', new_labels[order.dendrogram(.)]) %>% 
  color_branches(k = 5)

dend_list <- get_subdendrograms(dend, 5)

# Plotting the result
par(mfrow = c(2, 3))
plot(dend, main = "Original dendrogram")
sapply(dend_list, plot)

问题原因

核心问题是重复标签干扰了子树拆分逻辑。get_subdendrograms函数依赖树状图叶节点的唯一标识来定位并拆分出子树,当你将大量标签修改为重复的'Y'/'B'后,函数无法区分不同的叶节点,导致无法准确识别每个子树对应的节点集合,最终返回NULL。

解决方法

方法1:先拆分子树,再修改标签(推荐)

先基于原始唯一标签完成子树拆分,再逐个修改每个子树的显示标签和颜色,这样既保证拆分逻辑的正确性,又能实现所需的显示效果:

library(dplyr)
library(dendextend)

new_labels <- c("Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", 
                "Y", "B", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "B", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", 
                "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")

new_colors <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 
                1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
                8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
                1, 1, 1, 1)

# 1. 先构建树状图,保留原始唯一标签,完成子树拆分
dend <- iris[, -5] %>%
  dist() %>%
  hclust() %>%
  as.dendrogram() %>%
  color_branches(k = 5)

dend_list <- get_subdendrograms(dend, 5)

# 2. 对每个子树单独设置标签和颜色
dend_list <- lapply(dend_list, function(sub_dend) {
  # 获取当前子树叶节点的原始顺序索引
  sub_order <- order.dendrogram(sub_dend)
  # 匹配对应的新标签和颜色
  sub_labels <- new_labels[sub_order]
  sub_colors <- new_colors[sub_order]
  # 应用到子树
  sub_dend %>%
    set('labels_colors', sub_colors) %>%
    set('labels', sub_labels)
})

# 3. 修改原始树的标签和颜色用于对比展示
dend <- dend %>%
  set('labels_colors', new_colors[order.dendrogram(.)]) %>%
  set('labels', new_labels[order.dendrogram(.)])

# 绘图展示
par(mfrow = c(2, 3))
plot(dend, main = "Original dendrogram")
sapply(dend_list, plot)

方法2:保留原始标签,仅修改显示样式(可选)

如果不需要修改底层标签的唯一标识,只是想改变显示的文本样式,可以通过自定义绘图函数实现,避免修改labels属性影响拆分逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:47:02