EpiModel: Mathematical Modeling of Infectious Disease Dynamics

vers <- packageVersion("EpiModel")
year <- format(Sys.time(), "%Y")

What EpiModel Does

The EpiModel package provides tools for simulating mathematical models of infectious disease dynamics. It supports three model classes:

All three model classes share a unified API: configure inputs with param.*(), init.*(), and control.*(), then run simulations with dcm(), icm(), or netsim().

This vignette walks through the full network model pipeline, from network estimation through epidemic simulation and analysis.

The Network Model Pipeline

Step 1: Network Estimation

Network models begin with specifying and estimating the contact network. We define a network of 500 people, then estimate an ERGM that produces networks with a target mean degree of 0.7 (175 edges), limited concurrency (no more than 110 nodes with 2+ partners), and no one with 4+ partners. Partnerships last an average of 50 time steps.

library(EpiModel)
set.seed(12345)

nw <- network_initialize(n = 500)

formation <- ~edges + concurrent + degrange(from = 4)
target.stats <- c(175, 110, 0)
coef.diss <- dissolution_coefs(
  dissolution = ~offset(edges),
  duration = 50   # mean partnership duration in time steps
)

est <- netest(nw, formation, target.stats, coef.diss, verbose = FALSE)

Step 2: Network Diagnostics

Before using the estimated network in an epidemic model, we diagnose the fit. netdx simulates dynamic networks from the fitted model and compares summary statistics against targets. This is a critical validation step.

dx <- netdx(est, nsims = 5, nsteps = 500, verbose = FALSE)

The formation diagnostic shows how well the simulated networks maintain the target statistics (dashed lines) over time. The mean across simulations (solid line) and the interquartile range (shaded band) should track the targets closely:

plot(dx)

The duration diagnostic confirms that partnership durations match the specified target of 50 time steps:

plot(dx, type = "duration")

When the diagnostics miss their targets, or the estimation fails, the cause usually lies in the control settings that netest, netdx, and control.net pass to the ergm and tergm packages, or in the edges dissolution approximation at short partnership durations. The ?net-controls help page covers which settings to adjust at each stage, and the Improving Model Estimation and Simulation appendix of the NME course works through examples.

Step 3: Epidemic Simulation

With a validated network model, we layer on the epidemic. This SIS model uses a per-act transmission probability of 0.4, 2 acts per partnership per time step, and a recovery rate of 0.05. We seed 10 infections and run 3 stochastic simulations for 500 time steps.

param <- param.net(inf.prob = 0.4, act.rate = 2, rec.rate = 0.05)
init <- init.net(i.num = 10)
control <- control.net(type = "SIS", nsims = 3, nsteps = 500, verbose = FALSE)

sim <- netsim(est, param, init, control)

Step 4: Analyzing Results

Epidemic Trajectories

The default plot shows compartment sizes over time, with the mean across simulations (solid line), individual simulation traces, and a shaded interquartile range capturing stochastic variability:

plot(sim, sim.lines = TRUE, sim.alpha = 0.3,
     mean.lwd = 3, qnts = 0.5, main = "SIS Epidemic on a Dynamic Network")

For prevalence (proportions rather than counts), use popfrac = TRUE:

plot(sim, y = "i.num", popfrac = TRUE, sim.lines = TRUE, sim.alpha = 0.3,
     mean.lwd = 3, qnts = 0.5, main = "Infection Prevalence",
     ylab = "Prevalence", legend = FALSE)

Summary Statistics

summary reports means, standard deviations, and proportions across simulations at a specified time step:

summary(sim, at = 500)

Data Extraction

All epidemic data can be extracted as a data.frame for custom analysis---per-simulation values, means, or standard deviations across simulations:

d <- as.data.frame(sim)
head(d)

Transmission Trees

The transmission matrix records every infection event: who infected whom, when, and with what probability. This can be converted into a phylogenetic tree to visualize chains of transmission.

# Run a separate SI model seeded with a single infection for a cleaner tree
set.seed(42)
param2 <- param.net(inf.prob = 0.5, act.rate = 2)
init2 <- init.net(i.num = 5)
control2 <- control.net(type = "SI", nsims = 1, nsteps = 60, verbose = FALSE)
sim2 <- netsim(est, param2, init2, control2)

tm <- get_transmat(sim2)
head(tm)
tmPhylo <- as.phylo.transmat(tm)
par(mar = c(2, 1, 2, 1))
plot(tmPhylo, show.node.label = TRUE, root.edge = TRUE, cex = 0.5,
     main = "Transmission Tree")

Each tip is an infected person; each internal node (labeled with the infector's ID) is a transmission event. The horizontal axis shows time, revealing when and how the epidemic branched through the network.

Extending EpiModel

The built-in SI, SIR, and SIS models are starting points. EpiModel's extension API allows you to define custom models with arbitrary disease states, demographics, interventions, and feedback between the epidemic and the network. A custom module is simply a function that takes the simulation state (dat) and current time step (at), modifies state, and returns it:

# Example: a custom progression module for an SEIR model
progress_module <- function(dat, at) {
  active <- get_attr(dat, "active")
  status <- get_attr(dat, "status")

  # E -> I transition
  ids.EtoI <- which(active == 1 & status == "e" & runif(length(status)) < 0.1)
  status[ids.EtoI] <- "i"

  # I -> R transition
  ids.ItoR <- which(active == 1 & status == "i" & runif(length(status)) < 0.02)
  status[ids.ItoR] <- "r"

  dat <- set_attr(dat, "status", status)
  dat <- set_epi(dat, "ei.flow", length(ids.EtoI))
  dat <- set_epi(dat, "ir.flow", length(ids.ItoR))
  return(dat)
}

Custom modules are passed to control.net and integrated into the simulation loop. The EpiModel Gallery provides a library of worked extension examples, and the advanced vignettes in this package document the full API.

Learning Pathway

We recommend the following tiered sequence for learning EpiModel, consistent with the learning pathway on the EpiModel website. This is oriented towards those interested in stochastic network models, the primary focus of EpiModel.

Beginner

Intermediate

Advanced

Package Documentation

The current version of EpiModel is vr vers. Within the package, consult the help documentation for each exported function:

help(package = "EpiModel")

To see the latest updates, consult the NEWS file in the package or our GitHub Releases (https://github.com/EpiModel/EpiModel/releases).

Getting Help

Technical coding questions, conceptual modeling questions, and feature requests may be posted as GitHub issues at our main repository (https://github.com/EpiModel/EpiModel/issues).

Citation

If using EpiModel for teaching or research, please include a citation to our primary methods paper:

Jenness SM, Goodreau SM and Morris M. EpiModel: An R Package for Mathematical Modeling of Infectious Disease over Networks. Journal of Statistical Software. 2018; 84(8): 1-47. doi: 10.18637/jss.v084.i08 (https://doi.org/10.18637/jss.v084.i08).



Try the EpiModel package in your browser

Any scripts or data that you put into this service are public.

EpiModel documentation built on Oct. 16, 2026, 5:07 p.m.