45  The control.net Guide

Of the four functions that define an EpiModel network simulation, netest, param.net, init.net, and control.net, the last is the one students most often find opaque, and the one 2025 course participants asked us to explain in one place. control.net is the powerhouse: it does not describe the disease or the parameters, it wires together how the simulation runs, which model type, how the network evolves, which custom modules fire and in what order, and what gets recorded. Almost every advanced feature in this course and in the Gallery is switched on by an argument here.

This chapter is that single reference. The arguments are grouped by what they control, with the “why and when” for the ones that matter most, and a quick-reference table at the end. It is worth returning to whenever control.net comes up: every place you have already met it (the open-population model in Module 7, the SEIR extension earlier in this module) is using a slice of what follows.

45.1 1. What kind of model, and how much of it

These set the basic shape of the run.

control.net(type = "SI", nsteps = 500, nsims = 10, ncores = 5)
  • type names the built-in disease model ("SI", "SIS", "SIR"). Set type = NULL when you are writing an extension: it tells EpiModel not to pre-select any built-in infection/recovery modules, because you are supplying your own (Section 3). This is the single most common source of confusion in extension models, and it is not optional: EpiModel stops with an error (“Control parameter ‘type’ must be null if any user specified modules are present”) if type is left non-NULL while any custom module is present. Note that type = NULL disables only the automatic disease-module selection; the standard bookkeeping modules (initialization, network resimulation, prevalence, verbose) still run, so s.num, i.num, and num are recorded for you without any extra code.
  • nsteps is the number of time steps per simulation.
  • nsims is the number of independent stochastic replicates. Network models are stochastic, so you run many and summarize across them.
  • ncores parallelizes those replicates across CPU cores. Set it to the number of cores you can spare; nsims is divided among them.

45.2 2. How the network behaves during the run

These control whether and how the contact network changes as the epidemic runs.

  • resimulate.network (TRUE/FALSE). Whether the dynamic network is re-simulated step by step in response to the changing epidemic and demographic state. You need TRUE whenever the network itself must change during the run: because nodes arrive and depart (Module 7), because a formation term depends on an attribute the epidemic changes (serosorting, Module 7), or because layers depend on each other (Module 11). Setting it to FALSE does not mean a static network: the network is still dynamic, with partnerships forming and dissolving over time from the fitted TERGM, but it is simulated once in advance and then reused, with no feedback from the epidemic. A closed model whose formation formula does not depend on disease state can leave it FALSE.
  • tergmLite (TRUE/FALSE). The network storage mode. TRUE keeps only a lightweight snapshot (a networkLite), which is far faster and lower-memory and is essential for large or long research runs; the trade-off is that no full network history is retained, so you cannot reconstruct the network at past time points. FALSE (the default) keeps the complete networkDynamic history. Module 7 uses both deliberately: TRUE for the production runs, FALSE for the short diagnostic run where duration statistics are needed.
  • set.control.tergm passes control settings down to the TERGM machinery that actually redraws the network each step, in the form set.control.tergm = control.simulate.formula.tergm(...). The setting these models use is MCMC.burnin.min, raised well above its default of 1000 so the resimulated network is well mixed before statistics are read off it; the COVID model in Module 13 sets it in both its netdx call and its netsim call. Reach for it when netdx or the in-simulation network statistics sit off their targets in a way that looks like insufficient mixing rather than a misspecified model. Note that raising MCMC.burnin.min alone sets a floor; pinning the per-step burn-in exactly means setting MCMC.burnin.max to the same value, which the ERGM/TERGM controls chapter covers along with the rest of the per-step simulation controls.
  • nwstats.formula chooses which network statistics to monitor during the run (for post-simulation diagnostics). For a multi-layer model, wrap one formula per layer in multilayer(...), as in the Multi-Layer Networks tutorial.
  • dat.updates takes a callback function that EpiModel runs at set points each step, used in the dependent multi-layer model to keep the cross-layer degree attributes current. Most models leave it unset.

45.3 3. Wiring in your custom modules

This is the extension API from Module 9. In an extension model you replace or add process modules by passing your functions to the matching *.FUN slots.

control.net(type = NULL, nsteps = 500,
            infection.FUN  = infect,     # your transmission module
            progress.FUN   = progress,   # a custom progression module
            resimulate.network = TRUE)
  • Each *.FUN argument names a module function (infection.FUN, recovery.FUN, departures.FUN, arrivals.FUN, and any custom ones). Passing your own function overrides the built-in for that process.
  • Modules run in a fixed order each step; a custom module reads the state left by the ones before it and leaves state for the ones after. This is why the read-process-write contract from Module 9 matters: the order is part of the model.
  • With type = NULL, only the modules you supply run, so you have full control of the process, which is the whole point of an extension.

45.4 4. What gets recorded

By default EpiModel records the compartment counts and flows. These arguments record more.

  • epi.by adds compartment counts stratified by a nodal attribute, producing columns like i.num.risk0 / i.num.risk1 automatically. The attribute must already exist on the network as a nodal (vertex) attribute, and epi.by is currently limited to a single attribute. It is the general-attribute counterpart to the special group attribute.
  • Custom per-step statistics are not a control.net setting: you record them with set_epi() inside a module (the Module 9 module pattern), covered in the Model-Running APIs chapter.
  • cumulative.edgelist / save.cumulative.edgelist / truncate.el.cuml turn on partnership-history tracking, the basis for contact tracing and partner notification (again, the Model-Running APIs chapter).
  • save.network, save.transmat, save.nwstats control whether the network objects, the transmission matrix, and the monitored network statistics are attached to the output. They do not create those records: the transmission matrix, for instance, only exists if a module recorded it with set_transmat(), and save.transmat just decides whether to keep it. Under tergmLite = TRUE there is no network history to save.
  • verbose prints progress; set FALSE for clean output in loops and rendered documents.

45.5 5. Changing settings mid-run

  • .control.updater.list changes control settings at chosen time steps during a simulation (for example, turning off resimulate.network partway through). It is the control-side counterpart of the parameter updaters covered under scenarios and time-varying parameters. Most models never need it.

45.6 Quick reference

Argument Controls Reach for it when
type built-in disease model; NULL for extensions you are writing your own modules (type = NULL)
nsteps, nsims, ncores run length, replicates, parallelism always
resimulate.network redraw the network each step arrivals/departures, status-dependent formation, dependent layers
tergmLite lightweight vs full network storage large/long runs (TRUE); need network history (FALSE)
set.control.tergm (control.simulate.formula.tergm(), usually MCMC.burnin.min) how the network is re-simulated each step network statistics sit off target from insufficient mixing rather than misspecification
nwstats.formula (multilayer()) which network stats to monitor you want formation diagnostics, especially per layer
dat.updates per-step callback cross-layer dependency (Module 11)
*.FUN (e.g. infection.FUN) plug in custom module functions any extension model
epi.by stratified compartment counts you want outcomes by a nodal attribute
cumulative.edgelist, save.cumulative.edgelist, truncate.el.cuml partnership-history tracking contact tracing, partner notification, reachability
save.network, save.transmat, save.nwstats what to attach to the output post-hoc network / transmission analysis
.control.updater.list change control settings mid-run time-varying control settings
verbose progress printing quiet output in loops/documents

45.7 The full reference

This chapter is the working guide; the complete argument list and defaults are in ?control.net, and the mechanics behind the storage modes, trackers, and updaters are documented in the EpiModel package vignettes at epimodel.org.