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

如何用dendextend包提取R树状图节点坐标及分支起止/子节点信息

获取dendextend树状图的分支起止位置与节点子节点信息

一、获取所有节点的子节点信息

你可以通过dendextend::get_children()函数结合遍历提取每个节点的子节点;也可以用递归函数解析树状图结构,得到更清晰的层级关系。

方法1:遍历所有节点提取子节点

library(dendextend)

# 示例树状图(替换为你的树状图对象)
hc <- hclust(dist(iris[,1:4]))
dend <- as.dendrogram(hc)

# 获取所有节点的ID(叶子+内部节点)
all_node_ids <- seq_len(nleaves(dend) + ninternals(dend))

# 遍历每个节点,提取子节点(叶子节点返回NULL)
node_children_list <- lapply(all_node_ids, function(id) {
  current_node <- dend[[id]]
  if (is.leaf(current_node)) NULL else get_children(current_node)
})

# 命名列表,方便对应节点查看
names(node_children_list) <- paste0("node_", all_node_ids)

方法2:递归函数解析完整树结构

如果需要更直观的层级关系,用递归函数可以输出每个节点的路径和子节点:

get_full_tree_structure <- function(dend_node, node_path = c()) {
  if (is.leaf(dend_node)) {
    return(list(type = "leaf", label = attr(dend_node, "label"), path = node_path))
  } else {
    child_nodes <- lapply(seq_along(dend_node), function(i) {
      get_full_tree_structure(dend_node[[i]], c(node_path, i))
    })
    return(list(type = "internal", path = node_path, children = child_nodes))
  }
}

# 生成完整结构
tree_structure <- get_full_tree_structure(dend)

二、直接获取分支起止位置

如果不想自行计算,可通过dendrogram_to_gg()将树状图转换为ggplot对象,直接提取所有分支的线段数据:

# 转换为ggplot对象
gg_dend_obj <- dendrogram_to_gg(dend)

# 提取分支起止数据:包含x, xend, y, yend字段
branch_segments_data <- gg_dend_obj$data

如果要手动计算分支起止,可结合节点坐标和子节点信息:

# 获取所有节点坐标
nodes_xy <- get_nodes_xy(dend)

# 筛选内部节点(非叶子节点)
internal_node_ids <- which(!sapply(dend, is.leaf))

# 计算每个内部节点对应的分支线段
branch_details <- lapply(internal_node_ids, function(node_id) {
  parent_xy <- nodes_xy[node_id, ]
  child_nodes <- get_children(dend[[node_id]])
  
  # 匹配子节点的ID
  child1_id <- which(sapply(dend, function(n) identical(n, child_nodes[[1]])))
  child2_id <- which(sapply(dend, function(n) identical(n, child_nodes[[2]])))
  child1_xy <- nodes_xy[child1_id, ]
  child2_xy <- nodes_xy[child2_id, ]
  
  # 返回各段分支的起止坐标
  list(
    vertical_child1 = list(start = c(child1_xy[1], child1_xy[2]), end = c(child1_xy[1], parent_xy[2])),
    horizontal_parent = list(start = c(child1_xy[1], parent_xy[2]), end = c(child2_xy[1], parent_xy[2])),
    vertical_child2 = list(start = c(child2_xy[1], parent_xy[2]), end = c(child2_xy[1], child2_xy[2]))
  )
})

names(branch_details) <- paste0("branch_", internal_node_ids)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:47:49