Convert R Objects to Network Edgelists and Nodelists

Network analysis and plotting packages such as 'igraph', 'tidygraph', and 'ggraph' expect the edges and nodes of a graph as flat tables. Methods are provided to build those tables from data frames (column-pair edges chosen with 'tidyselect' semantics), tree-based model objects ('randomForest', 'tree', 'rpart', 'xgboost', 'gbm'), lists (recursive parent-child edges), and atomic vectors (sequential edges). Graphs can also be constructed in one step via as.igraph() and as_tbl_graph() methods for tree models.


networkformat

R-CMD-check Lifecycle:experimental

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 1

Lists

Any list becomes a recursive parent-child edgelist. Nested lists create deeper edges with path-style IDs.

edgelist(list(a = list(b = 1, c = 2), d = 3))
#>     from       to depth
#> 1   root   root/a     1
#> 2 root/a root/a/b     2
#> 3 root/a root/a/c     2
#> 4   root   root/d     1

# S3 objects without a dedicated method are decomposed as plain lists
edgelist(lm(y ~ x, data.frame(x = 1:3, y = 1:3)))

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 is NA
  • symmetric_cols — mark target columns as undirected; adds a directed column
  • dedupe = TRUE (default) — when using symmetric_cols, keep only one direction (from <= to)
  • weights = TRUE — collapse identical rows and add a weight count 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, label

tree

library(tree)

tr <- tree(Species ~ Sepal.Length + Sepal.Width, data = iris)

# Edgelist with parsed split components
el <- edgelist(tr)
head(el)
#> Columns: from, to, label, split_var, split_op, split_point

# Node list
nl <- nodelist(tr)
head(nl)
#> Columns: name, var, n, dev, yval, is_leaf, label

Graph 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:

  1. Create R/edgelist.newclass.R with edgelist.newclass(input_object, ...)
  2. Add @export roxygen tag
  3. Run devtools::document() to update NAMESPACE
  4. Add tests in tests/testthat/
  5. See R/edgelist.randomForest.R as a reference

Related packages

  • randomForest — random forest models
  • tree — classification and regression trees
  • rpart — recursive partitioning trees
  • xgboost — gradient boosting
  • gbm — generalized boosted models
  • igraph — network analysis and visualization
  • tidygraph — tidy graph manipulation
  • ggraph — grammar of graphics for networks

License

MIT

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.