networkformat converts R objects into network edgelist/nodelist format for visualization and analysis with packages like igraph, tidygraph, and ggraph. It works with tree-based ML models (randomForest, tree, rpart, xgboost, gbm), data frames, lists, and vectors.
Full documentation at https://jessebrandtdata.github.io/networkformat/.
Installation
# install.packages("devtools")
devtools::install_github("jessebrandtdata/networkformat")Quick start
library(networkformat)
# Vectors --- sequential chain of edges
edgelist(c("A", "B", "C", "D"))
#> from to
#> 1 A B
#> 2 B C
#> 3 C D
nodelist(c("A", "B", "A", "C"))
#> name n
#> 1 A 2
#> 2 B 1
#> 3 C 1
# Data frames --- column pairs become edges
edgelist(courses, source_cols = course, target_cols = prereq)
# Tree models --- one-step graph conversion
library(tree)
tr <- tree(Species ~ ., data = iris)
as.igraph(tr)Supported inputs
| Input | edgelist() |
nodelist() |
as.igraph() / as_tbl_graph()
|
|---|---|---|---|
| vector (character, numeric, …) | sequential edges i -> i+1
|
unique values with frequency | — |
| list | recursive parent-child edges | node metadata (type, depth, children) | — |
| data.frame | column-pair edges | reorder with id_col first |
— |
| randomForest | parent-child splits | node attributes with labels | single or multi-tree graph |
| tree | parent-child splits | node attributes with labels | full tree graph |
| rpart | parent-child splits | node attributes with labels | full tree graph |
| xgb.Booster (xgboost) | parent-child splits | node attributes with labels | single or multi-tree graph |
| gbm | parent-child splits | node attributes with labels | single or multi-tree graph |
Vectors
Any atomic vector becomes a sequential edgelist: element i connects to element i + 1.
edgelist(c("intro", "basics", "advanced", "project"))
#> from to
#> 1 intro basics
#> 2 basics advanced
#> 3 advanced project
# Collapse duplicate edges with a count
edgelist(c("A", "B", "A", "B", "C"), weights = TRUE)
#> from to weight
#> 1 A B 2
#> 2 B A 1
#> 3 B C 1
# Node list gives unique values and frequencies
nodelist(c("A", "B", "A", "B", "C"))
#> name n
#> 1 A 2
#> 2 B 2
#> 3 C 1Lists
Any list becomes a recursive parent-child edgelist. Nested lists create deeper edges with path-style IDs.
Data frames
Specify which columns are source/target nodes. All other columns are carried as edge attributes by default.
# Basic edgelist from two columns
edgelist(courses, source_cols = course, target_cols = prereq)
# Multiple target columns (Cartesian product of source x target)
edgelist(courses, source_cols = course, target_cols = c(prereq, crosslist))
# Keep only specific attribute columns
edgelist(courses, source_cols = course, target_cols = prereq,
attr_cols = c(dept, credits))
# Symmetric (undirected) edges with deduplication
edgelist(courses, source_cols = course,
target_cols = c(prereq, crosslist),
symmetric_cols = crosslist)
# Collapse duplicate rows and count them
edgelist(courses, source_cols = course, target_cols = prereq,
weights = TRUE)Key parameters:
-
na.rm = TRUE(default) — remove edges where from or to isNA -
symmetric_cols— mark target columns as undirected; adds adirectedcolumn -
dedupe = TRUE(default) — when usingsymmetric_cols, keep only one direction (from <= to) -
weights = TRUE— collapse identical rows and add aweightcount column
Tree models
randomForest
library(randomForest)
rf <- randomForest(Species ~ ., data = iris, ntree = 5)
# Edgelist for all trees
el <- edgelist(rf)
head(el)
#> Columns: from, to, split_var, split_point, prediction, direction, treenum, split_var_name
# Extract specific trees
el_1 <- edgelist(rf, treenum = 1)
el_13 <- edgelist(rf, treenum = c(1, 3))
# Node list
nl <- nodelist(rf)
head(nl)
#> Columns: name, is_leaf, split_var, split_var_name, split_point, prediction, treenum, labelGraph conversion
Skip the edgelist/nodelist step and go straight to an igraph or tbl_graph:
library(tree)
library(igraph)
library(tidygraph)
tr <- tree(Species ~ ., data = iris)
# igraph
g <- as.igraph(tr)
# tidygraph
tg <- as_tbl_graph(tr)
# randomForest (single tree or multiple as disconnected components)
library(randomForest)
rf <- randomForest(Species ~ ., data = iris, ntree = 3)
g_rf <- as.igraph(rf, treenum = 1)Visualization
library(ggraph)
library(tidygraph)
library(tree)
tr <- tree(Species ~ ., data = iris)
as_tbl_graph(tr) |>
ggraph(layout = "tree") +
geom_edge_link(arrow = arrow(length = unit(2, "mm")),
end_cap = circle(3, "mm")) +
geom_node_point(aes(color = is_leaf), size = 4) +
geom_node_text(aes(label = label), size = 3, vjust = -0.8) +
theme_graph()Extending the package
To add support for a new model class:
- Create
R/edgelist.newclass.Rwithedgelist.newclass(input_object, ...) - Add
@exportroxygen tag - Run
devtools::document()to update NAMESPACE - Add tests in
tests/testthat/ - See
R/edgelist.randomForest.Ras a reference