The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

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:

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

License

MIT

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.