Skip to contents

An R package for analyzing temporal relational data using Dynamic Bilinear Network (DBN) models. Supports ordinal, Gaussian, and binary outcomes across static, dynamic, low-rank, and HMM model variants for unipartite, bipartite, and symmetric (undirected) networks.

Installation

Prerequisites

This package uses OpenMP for parallel computing. Setup by platform:

macOS:

  1. Install Xcode Command Line Tools:
xcode-select --install
  1. Install gfortran (includes OpenMP support):

Linux:

  • OpenMP is typically pre-installed with GCC
  • If compilation fails, install:
# Ubuntu/Debian
sudo apt-get install libomp-dev

# RHEL/CentOS/Fedora
sudo yum install libomp-devel

Windows:

  • Install Rtools matching your R version
  • OpenMP is included automatically

Install Package

# Install from GitHub
devtools::install_github("netify-dev/dbn")

Troubleshooting

If installation fails, verify your setup:

# Test if compilers work
install.packages("minpack.lm", type = "source")

# Check your R version
R.version.string

Common macOS Issues:

  • If you see “gfortran not found”, add to your ~/.zshrc:
export PATH="/opt/gfortran/bin:$PATH"

Then restart your terminal and R.

  • For persistent OpenMP errors on macOS, you may need to create ~/.R/Makevars with appropriate compiler flags. Here an example:
# gfortran 14.2 configuration for R 4.5.1 on ARM64 Mac
FC = /opt/gfortran/bin/gfortran
F77 = /opt/gfortran/bin/gfortran

# Use the actual path where libgfortran.dylib is located
FLIBS = -L/opt/gfortran/lib/gcc/aarch64-apple-darwin20.0/14.2.0 -L/opt/gfortran/lib -lgfortran -lquadmath -lm

# Compiler flags
FCFLAGS = -mmacosx-version-min=11.0
FFLAGS = -mmacosx-version-min=11.0

# brew
CPPFLAGS = -I/opt/homebrew/include
LDFLAGS = -L/opt/homebrew/lib

Quick Start

library(dbn)

# Set number of threads for parallel computation (optional)
set_dbn_threads(min(4, parallel::detectCores(logical = FALSE)))

# Simulate ordinal network data
sim <- simulate_static_dbn(n = 15, p = 1, time = 10, seed = 42)

# Fit static model
fit <- dbn(
  sim$Y,
  model = "static",
  family = "ordinal",
  nscan = 1000,
  burn = 500,
  odens = 1
)

# Diagnostics
summary(fit)
plot(fit)
check_convergence(fit)
plot_trace(fit)

# Posterior predictive checks
ppd <- posterior_predict_dbn(fit, ndraws = 100)
plot_ppc_ecdf(fit, ppd, Y_obs = sim$Y)

Models

All models share the bilinear form Theta_t = A_t * Theta_{t-1} * B_t' + M + noise.

Static DBN (model = "static")

  • Fixed sender/receiver effects (A, B constant)
  • Good for smaller datasets or cross-sectional data (T=1)

Dynamic DBN (model = "dynamic")

  • Time-varying A_t and B_t matrices estimated via FFBS
  • Auto-selects time-thinning for large networks to manage memory
  • Optional AR(1) dynamics for A and B

Low-Rank DBN (model = "lowrank")

  • A_t = U diag(alpha_t) U' with U on the Stiefel manifold
  • Better scalability for networks with many nodes (50+)

HMM DBN (model = "hmm")

  • Regime-switching: A_t and B_t selected from R discrete regimes
  • Regime transitions governed by a Markov chain with estimated transition matrix
  • Use plot_regime_probs() to visualize regime assignments

Symmetric Networks (symmetric = TRUE)

All models except low-rank support a symmetric = TRUE option that constrains B = A, appropriate for undirected networks where sender and receiver dynamics are identical. Requires square networks (n_row == n_col).

Outcome Families

  • family = "ordinal": Ordered categorical data via rank likelihood
  • family = "gaussian": Continuous data with estimated observation variance
  • family = "binary": Binary (0/1) data via probit link with data augmentation

Main Functions

Model Fitting

Simulation

Posterior Analysis

Visualization

Forecasting and IRF

Utilities

Data Format

Input data should be a 4-dimensional array:

  • Dimension 1: Sender actors (n_row)
  • Dimension 2: Receiver actors (n_col, can differ from n_row for bipartite networks)
  • Dimension 3: Relation types
  • Dimension 4: Time points

3D arrays (actors x actors x time) are auto-promoted to 4D with a single relation.

For cross-sectional data (T=1), dbn() automatically selects the static model.

Vignettes

After installation, browse the vignettes for detailed tutorials:

License

MIT License - see LICENSE file for details.