25  Lab 2 (Mixing & Concurrency)

In this lab, you will simulate a network-based epidemic model with population heterogeneity, building on the two-group model in the Nodal Attributes tutorial. This uses the special group attribute, so you can explore variation in both the epidemic parameters and the network structure.

The lab comes in two parts. Part 1 is the main exercise and everyone should work through it. Part 2 is optional, for those who finish early or want to push further into the mixing model; it is more demanding than anything else in this module, so treat it as a stretch rather than a requirement.

Learning objectives for Part 1:

Learning objectives for Part 2:

Note

A worked solution is in the course repository as mod4-NodalAttributes-Lab2.R. Please work through the lab yourself before you consult it. You will get much more out of the questions if you have already formed your own answer.

25.1 Setup

Start by clearing your R object environment, so that nothing lingers from the tutorial:

Code
rm(list = ls())

Because you have just cleared the environment, est from the tutorial is gone. Your first task is to rebuild it.

NoteRebuild the tutorial’s network model

Re-create the 500-node network with the group attribute, re-specify the same formation and dissolution models and target statistics, and re-estimate with netest. All of this code is in the Nodal Attributes tutorial. Estimation takes only a second or two, so this is quick, and it is worth typing out rather than copying: it is the last time in this module you will build a two-group model from scratch.

25.2 Part 1: Group-Specific Acquisition Probability

The tutorial ran the epidemic with the same per-act acquisition probability in both groups (inf.prob = 0.3, inf.prob.g2 = 0.3). Here we ask what changes when the two groups differ.

NotePart 1 steps
  • Run the tutorial’s model again with the equal-risk parameters, so you have a baseline to compare against. Calculate the cumulative number of infections in each group by summing si.flow and si.flow.g2 (a count of incident infections, not the cumulative-incidence proportion). To get those sums, pull the run out with as.data.frame(sim, out = "mean"), then add na.rm = TRUE to your sum() so the undefined first step is dropped.
  • Scenario A. Change the epidemic parameters so that women (group 1) have twice the per-act acquisition probability of men (group 2), 60% versus 30%. Inspect the group-specific prevalence and incidence plots, and calculate the cumulative number of infections in each group. Compare against your baseline. Do not be surprised if the cumulative total barely moves while the peak and timing shift: that near-null change in the total is the informative result here, not a sign you did something wrong. Question 1 asks you to explain it.
  • Scenario B. Now lower the men’s per-act acquisition probability to 10%, keeping women at 60%. Calculate and inspect all of the same statistics.
NotePart 1 questions
  1. Doubling women’s per-act acquisition probability from 30% to 60% does not double their cumulative number of infections. Why not? What is limiting it?
  2. In Scenario B you lowered the men’s acquisition probability, and the women’s cumulative number of infections fell as well. Why should changing men’s parameter affect women’s outcome at all?
  3. Look back at your baseline, where both groups had identical acquisition probabilities and identical mean degree. The two groups still do not have the same cumulative number of infections. What is producing that difference?

25.3 Part 2: Relaxing the All-Cross-Sex Assumption (Optional)

The tutorial set the nodematch("group") target statistic to 0, so that none of the relations were within group. That is an absolute mixing rule: a prohibition. Mixing in real populations is more often statistical: a tendency. Here we relax the prohibition and see what it costs us.

You will need one diagnostic that the tutorial did not use. The nodefactor term counts tie-ends per group, so nodefactor.group.k divided by the group’s size is that group’s mean degree. Use this helper to pull it out of a netdx object:

Code
mixing_check <- function(dx, label) {
  s <- get_nwstats(dx)
  out <- data.frame(model = label,
                    FF = mean(s$nodematch.group.1),
                    MM = mean(s$nodematch.group.2),
                    meandeg.F = mean(s$nodefactor.group.1) / 250,
                    meandeg.M = mean(s$nodefactor.group.2) / 250)
  out$ratio.M.over.F <- out$meandeg.M / out$meandeg.F
  out
}

and monitor these statistics in netdx:

Code
mon <- ~edges + nodematch("group", diff = TRUE) +
  nodefactor("group", levels = NULL) + concurrent(by = "group")
NotePart 2 steps
  1. Make the simple change. In a 250/250 population, random mixing would make about half of all ties same-sex. Leave everything else exactly as the tutorial had it, and just change the nodematch("group") target statistic from 0 to half the number of edges. Re-estimate, then diagnose with netdx using the mon formula above, and run mixing_check on the result. Compare it against the tutorial’s model. Check the netdx table carefully: did every target statistic you set get met?
  2. Fix it. Work out from the step-1 output what went wrong, then re-specify the formation model using nodematch("group", diff = TRUE), which reports the within-group tie counts separately for each group instead of pooling them. You will need one more target statistic than before. Re-estimate, re-diagnose, and re-run mixing_check.
  3. Run the epidemic both ways. Simulate the SIR epidemic on the tutorial’s original model and on your fixed model, using the tutorial’s equal-risk parameters for both. Compare the cumulative number of infections in each group across the two networks.
NotePart 2 questions
  1. In step 1, every target statistic you set was met, and yet the two groups’ mean degrees came apart. How can both of those be true at once? (Hint: count tie-ends. If FF is the number of within-women ties, MM the within-men ties, and FM the cross-sex ties, how many tie-ends do women have? How many do men? What does nodematch("group") actually pin down?)
  2. What happened to the two groups’ cumulative number of infections when you moved from the tutorial’s model to your fixed model? Be careful how hard you lean on a single run here.
  3. In Part 1 question 3 you explained why women carried the higher burden even at equal risk. Does that explanation still hold in your fixed model? If not, what changed?

25.4 Additional Exploration

  • Change the same-sex target in Part 2 from 50% to 20% or 80%, and re-run steps 1 and 2. How does the size of the divergence track the target?
  • Set the two diff = TRUE targets to different values on purpose (say 60 and 22.5). Predict the two mean degrees from your Part 2 question 1 answer before you fit the model, then check yourself.
  • Make the concurrency targets equal in the two groups (10% each) and re-run Part 2 step 1. Does the naive model still diverge? Why not?