Introduction to BrainNetTest

Maximiliano Martino, Daniel Fraiman

2026-04-20

Overview

BrainNetTest implements the non-parametric L1-distance ANOVA test of Fraiman and Fraiman (2018) for comparing populations of brain networks represented as graphs. The package provides:

This vignette introduces the basic API on simple synthetic data. The companion vignette, Generating and Analyzing Brain Networks with Community Structures, shows the full pipeline on community-structured populations.

Installation

# Release version (once on CRAN)
install.packages("BrainNetTest")

# Development version from GitHub
# install.packages("remotes")
remotes::install_github("mmaximiliano/BrainNetTest")

A minimal example

library(BrainNetTest)
set.seed(1)

Generating random graphs

generate_random_graph() returns a symmetric binary adjacency matrix with no self-loops:

G <- generate_random_graph(n_nodes = 10, edge_prob = 0.2)
isSymmetric(G)
#> [1] TRUE
all(diag(G) == 0)
#> [1] TRUE

Central graph and Manhattan distance

Given a population (list of adjacency matrices), the central graph is the entry-wise mean; compute_distance() returns the L1 (Manhattan) distance between two graphs:

population <- replicate(
  5, generate_random_graph(n_nodes = 10, edge_prob = 0.2),
  simplify = FALSE)

central <- compute_central_graph(population)
compute_distance(population[[1]], central)
#> [1] 18

The group test statistic T

compute_test_statistic() aggregates within- and between-group Manhattan distances into the statistic T. Larger values indicate stronger evidence that the groups differ:

control <- replicate(
  15, generate_random_graph(n_nodes = 10, edge_prob = 0.20),
  simplify = FALSE)
patient <- replicate(
  15, generate_random_graph(n_nodes = 10, edge_prob = 0.40),
  simplify = FALSE)

populations <- list(Control = control, Patient = patient)
compute_test_statistic(populations, a = 1)
#>   Control 
#> -18.54162

Global test and critical edges

identify_critical_links() combines the global permutation test with an iterative edge-removal procedure that returns the edges driving the observed difference:

result <- identify_critical_links(
  populations,
  alpha          = 0.05,
  method         = "fisher",
  n_permutations = 200,
  seed           = 42)

head(result$critical_edges)
#>    node1 node2    p_value
#> 5      2     4 0.01419290
#> 40     4    10 0.01419290
#> 8      2     5 0.02093953
#> 38     2    10 0.02093953
#> 44     8    10 0.02532769
#> 2      1     3 0.03518241

The get_critical_nodes() helper summarises this result at the node level:

get_critical_nodes(result)
#>   node critical_degree
#> 1    2               3
#> 2    4               3
#> 3   10               3
#> 4    1               1
#> 5    3               1
#> 6    5               1
#> 7    6               1
#> 8    8               1

References

Fraiman, D. and Fraiman, R. (2018) An ANOVA approach for statistical comparisons of brain networks. Scientific Reports, 8, 4746. https://doi.org/10.1038/s41598-018-21688-0