如何用R构建带分类计数的层级树状图?已尝试data.tree遇阻
层级分类计数树的构建方案(R语言)
需求说明
需要构建层级图展示数据框中不同分类的计数,层级越往下分类越具体;要求能根据数据框和指定层级变量自动统计各分类的数量,且方案可重复应用于不同数据集。
示例数据
tree_data = data.frame(Context = c("urban", "rural", "urban", "urban", "rural", "rural"), Lighting = c("daylight", "dark", "dark", "daylight", "daylight", "dark"), Driver_age = c("Senior", "Adult", "Adult", "Adult", "Adult", "Senior"))
现有基础操作
已使用data.tree包构建基础层级结构:
library(data.tree) tree_data$pathString = paste("crashes", tree_data$Context, tree_data$Lighting, tree_data$Driver_age, sep = "/") crashes = as.Node(tree_data) print(crashes)
后续解决方案
1. 为节点添加计数属性
data.tree的节点自带totalCount属性,代表该节点下包含的叶子节点总数(即对应分组的观测计数)。可以通过Do()方法将该值赋值为自定义的Count属性,方便后续调用:
# 为每个节点添加Count属性 crashes$Do(function(node) { node$Count <- node$totalCount }) # 查看带计数的节点结构 print(crashes, "Count")
输出示例:
levelName Count 1 crashes 6 2 ¦--urban 3 3 ¦ ¦--daylight 2 4 ¦ ¦ °--Senior 1 5 ¦ ¦ °--Adult 1 6 ¦ °--dark 1 7 ¦ °--Adult 1 8 °--rural 3 9 ¦--dark 2 10 ¦ °--Adult 1 11 ¦ °--Senior 1 12 °--daylight 1 13 °--Adult 1
2. 可视化层级计数树
推荐使用networkD3包生成交互式层级树图,既美观又易于适配不同数据集:
library(networkD3) # 将data.tree节点转换为networkD3所需的列表格式 tree_list <- ToListExplicit(crashes, unname = TRUE) # 为节点名称添加计数标注 add_count_label <- function(node) { node$name <- paste0(node$name, " (", node$Count, ")") if (!is.null(node$children)) { node$children <- lapply(node$children, add_count_label) } return(node) } tree_list <- add_count_label(tree_list) # 生成交互式树图 diagonalNetwork( List = tree_list, nodeSize = JS("function(d) { return d.Count * 10; }"), # 根据计数调整节点大小 textColour = "#333", opacity = 0.9, margin = list(top = 10, right = 100, bottom = 10, left = 100) )
如果需要静态图,可以使用data.tree自带的plot()函数,配合nodeLabel参数显示计数:
plot(crashes, nodeLabel = function(node) paste(node$name, "\n(", node$Count, ")", sep = ""), edgeLabel = NULL)
3. 通用函数封装
将上述步骤封装为可复用函数,只需传入数据框和层级变量即可生成带计数的层级树:
library(data.tree) library(networkD3) library(jsonlite) build_count_tree <- function(data, hierarchy_vars) { # 构建pathString data$pathString <- paste("root", do.call(paste, c(data[hierarchy_vars], sep = "/")), sep = "/") # 转换为节点对象 tree <- as.Node(data) # 添加计数属性 tree$Do(function(node) node$Count <- node$totalCount) # 处理节点名称,添加计数标注 tree_list <- ToListExplicit(tree, unname = TRUE) add_count_label <- function(node) { node$name <- paste0(node$name, " (", node$Count, ")") if (!is.null(node$children)) { node$children <- lapply(node$children, add_count_label) } return(node) } tree_list <- add_count_label(tree_list) # 生成交互式可视化 p <- diagonalNetwork( List = tree_list, nodeSize = JS("function(d) { return d.Count * 10; }"), textColour = "#333", opacity = 0.9, margin = list(top = 10, right = 100, bottom = 10, left = 100) ) # 返回树对象和可视化结果 return(list(tree = tree, plot = p)) } # 使用示例 result <- build_count_tree(tree_data, c("Context", "Lighting", "Driver_age")) # 查看树结构 print(result$tree, "Count") # 显示可视化图 result$plot
内容的提问来源于stack exchange,提问作者Kelly
相关产品推荐
相关产品推荐

