在R语言中获取树结构各节点下方层数的技术实现求助
Hey there! Let's work through how to calculate the number of levels below each node in your tree structure using R. I know you tried data.tree without luck, so I'll start by fixing that approach, then show you an alternative with igraph that might click better for edge list data.
data.tree (Fixed!) The likely issue with your initial data.tree attempt was mixing up parent-child relationships in your edge list. Your (from, to) pairs represent child nodes pointing to their parents (e.g., A's parent is Z), but data.tree expects parent-to-child edges by default. Here's how to fix it:
- Prepare your edge data and reformat it to explicitly define parent-child relationships:
library(data.tree) # Your original edge list edges <- data.frame( from = c("A", "B", "C", "D", "E", "F", "G", "H", "I"), to = c("Z", "Z", "A", "A", "A", "D", "D", "G", "C") ) # Restructure to parent (to) -> child (from) tree_df <- data.frame(parent = edges$to, child = edges$from)
- Build the tree using
FromDataFrameNetwork, which reads parent-child edge lists:
tree <- FromDataFrameNetwork(tree_df)
- Calculate levels below each node using the
heightproperty ofdata.treenodes. This property gives the longest path length (in edges) from the node to its farthest leaf—exactly the "levels below" value you need:
# Extract node names and their corresponding levels below node_levels <- data.frame( Node = tree$Get("name"), Levels_Below = tree$Get("height") ) # Reorder to match your expected output (optional) node_levels <- node_levels[match(c("A", "B", "C", "D", "E", "F", "G", "H", "I", "Z"), node_levels$Node), ] # Print the result print(node_levels, row.names = FALSE)
This will output exactly the result you're looking for:
Node Levels_Below A 3 B 0 C 1 D 2 E 0 F 0 G 1 H 0 I 0 Z 4
igraph If you prefer working with graph theory tools, igraph is a great alternative for edge list data. Here's how to get the same result:
- Create a directed graph from your edge list, then reverse the edges to get parent-to-child directionality:
library(igraph) # Your edge list edges <- data.frame( from = c("A", "B", "C", "D", "E", "F", "G", "H", "I"), to = c("Z", "Z", "A", "A", "A", "D", "D", "G", "C") ) # Build graph (child -> parent), then reverse to parent -> child g <- graph_from_data_frame(edges, directed = TRUE) g_rev <- reverse_edges(g)
- Identify leaf nodes (nodes with no children, i.e., out-degree 0):
leaves <- V(g_rev)[degree(g_rev, mode = "out") == 0]$name
- Calculate the longest path from each node to any leaf:
# For each node, find the maximum path length to any leaf levels_below <- sapply(V(g_rev)$name, function(node) { max(sapply(leaves, function(leaf) { path_length <- shortest.paths(g_rev, v = node, to = leaf, mode = "out") if (is.infinite(path_length)) 0 else path_length })) }) # Format the result result <- data.frame(Node = names(levels_below), Levels_Below = levels_below) result <- result[match(c("A", "B", "C", "D", "E", "F", "G", "H", "I", "Z"), result$Node), ] # Print the result print(result, row.names = FALSE)
This will also produce your desired output.
内容的提问来源于stack exchange,提问作者Aaron K.

