Contact Matrix Examples
contact_matrix_examples.RmdThis vignette demonstrates how to set up contact matrices for age- and school-structured models using examples.
First we define the age groups we want to use, and the population sizes of each group:
# under 1, 1-4, 5-11, 12-13, 14-17, 18-24, 25-44, 45-69, 70 plus
agelims <- c(0, 1, 5, 12, 14, 18, 25, 45, 70)
agepops <- c(100, 400, 700, 200, 400, 700, 2000, 2400, 1000)Here’s how to generate a contact matrix using Polymod data, which is
contact survey data from the well known “Polymod” study. When including
the second argument to the contactMatrixPolymod() function,
the contact matrix will be adjusted to fit the population distribution
defined above in the agepops variable.
cmp <- contactMatrixPolymod(agelims, agepops)
knitr::kable(round(cmp, 2), format = "markdown")| under1 | 1to4 | 5to11 | 12to13 | 14to17 | 18to24 | 25to44 | 45to69 | 70+ | |
|---|---|---|---|---|---|---|---|---|---|
| under1 | 0.42 | 0.72 | 0.57 | 0.09 | 0.21 | 0.32 | 2.11 | 1.14 | 0.13 |
| 1to4 | 0.18 | 2.98 | 1.52 | 0.16 | 0.24 | 0.49 | 3.28 | 1.89 | 0.35 |
| 5to11 | 0.08 | 0.87 | 8.79 | 0.82 | 0.46 | 0.46 | 3.35 | 1.88 | 0.37 |
| 12to13 | 0.04 | 0.32 | 2.86 | 7.98 | 2.50 | 0.57 | 2.77 | 2.22 | 0.47 |
| 14to17 | 0.05 | 0.24 | 0.80 | 1.25 | 9.67 | 2.21 | 2.71 | 2.51 | 0.37 |
| 18to24 | 0.05 | 0.28 | 0.46 | 0.16 | 1.26 | 5.72 | 3.68 | 2.87 | 0.37 |
| 25to44 | 0.11 | 0.66 | 1.17 | 0.28 | 0.54 | 1.29 | 5.72 | 3.83 | 0.61 |
| 45to69 | 0.05 | 0.32 | 0.55 | 0.18 | 0.42 | 0.84 | 3.20 | 4.27 | 0.96 |
| 70+ | 0.01 | 0.14 | 0.26 | 0.09 | 0.15 | 0.26 | 1.22 | 2.30 | 1.57 |
The sum of each row represents the relative overall contact rate of each group:
| total | |
|---|---|
| under1 | 5.72 |
| 1to4 | 11.11 |
| 5to11 | 17.09 |
| 12to13 | 19.74 |
| 14to17 | 19.82 |
| 18to24 | 14.86 |
| 25to44 | 14.20 |
| 45to69 | 10.78 |
| 70+ | 6.01 |
Those row sums can be factored out to generate the fraction of each group’s contacts that are with each group: The sum of each row represents the relative overall contact rate of each group:
| under1 | 1to4 | 5to11 | 12to13 | 14to17 | 18to24 | 25to44 | 45to69 | 70+ | |
|---|---|---|---|---|---|---|---|---|---|
| under1 | 0.07 | 0.13 | 0.10 | 0.02 | 0.04 | 0.06 | 0.37 | 0.20 | 0.02 |
| 1to4 | 0.02 | 0.27 | 0.14 | 0.01 | 0.02 | 0.04 | 0.29 | 0.17 | 0.03 |
| 5to11 | 0.00 | 0.05 | 0.51 | 0.05 | 0.03 | 0.03 | 0.20 | 0.11 | 0.02 |
| 12to13 | 0.00 | 0.02 | 0.14 | 0.40 | 0.13 | 0.03 | 0.14 | 0.11 | 0.02 |
| 14to17 | 0.00 | 0.01 | 0.04 | 0.06 | 0.49 | 0.11 | 0.14 | 0.13 | 0.02 |
| 18to24 | 0.00 | 0.02 | 0.03 | 0.01 | 0.08 | 0.38 | 0.25 | 0.19 | 0.03 |
| 25to44 | 0.01 | 0.05 | 0.08 | 0.02 | 0.04 | 0.09 | 0.40 | 0.27 | 0.04 |
| 45to69 | 0.00 | 0.03 | 0.05 | 0.02 | 0.04 | 0.08 | 0.30 | 0.40 | 0.09 |
| 70+ | 0.00 | 0.02 | 0.04 | 0.02 | 0.02 | 0.04 | 0.20 | 0.38 | 0.26 |
Now we show how to split the age groups for elementary school (5-11), middle school (12-13), and high school (18-24) into two schools each:
schoolagegroups <- c(3, 3, 4, 4, 5, 5) #The indices of the age group for each school
schoolpops <- c(350, 350, 100, 100, 200, 200) #The number of students in each schoolThe socialmixr R package includes functions that allow
us to see the number of contacts of school-aged children that occurred
overall vs. just at school:
cmAll <- suppressMessages(
suppressWarnings(socialmixr::contact_matrix(socialmixr::polymod,
age.limits = agelims)$matrix))
cmSchool <- suppressMessages(
suppressWarnings(socialmixr::contact_matrix(socialmixr::polymod,
age.limits = agelims,
filter = list(cnt_school = 1))$matrix))
knitr::kable(round(cmAll, 2), format = "markdown")| [0,1) | [1,5) | [5,12) | [12,14) | [14,18) | [18,25) | [25,45) | [45,70) | 70+ | |
|---|---|---|---|---|---|---|---|---|---|
| [0,1) | 0.33 | 0.83 | 0.75 | 0.10 | 0.33 | 0.55 | 3.72 | 1.82 | 0.16 |
| [1,5) | 0.07 | 2.34 | 1.38 | 0.19 | 0.25 | 0.51 | 3.62 | 1.81 | 0.32 |
| [5,12) | 0.03 | 0.64 | 7.43 | 0.86 | 0.45 | 0.44 | 3.68 | 1.76 | 0.30 |
| [12,14) | 0.03 | 0.17 | 1.99 | 7.14 | 2.47 | 0.63 | 3.35 | 2.03 | 0.35 |
| [14,18) | 0.01 | 0.17 | 0.65 | 1.07 | 9.10 | 2.11 | 2.98 | 2.15 | 0.21 |
| [18,25) | 0.01 | 0.21 | 0.41 | 0.13 | 1.22 | 5.64 | 4.14 | 2.63 | 0.29 |
| [25,45) | 0.04 | 0.53 | 1.03 | 0.23 | 0.53 | 1.29 | 6.55 | 3.52 | 0.44 |
| [45,70) | 0.02 | 0.26 | 0.50 | 0.18 | 0.46 | 0.91 | 4.01 | 4.34 | 0.74 |
| 70+ | 0.01 | 0.11 | 0.25 | 0.10 | 0.20 | 0.31 | 1.72 | 2.75 | 1.48 |
| [0,1) | [1,5) | [5,12) | [12,14) | [14,18) | [18,25) | [25,45) | [45,70) | 70+ | |
|---|---|---|---|---|---|---|---|---|---|
| [0,1) | 0.14 | 0.09 | 0.03 | 0.00 | 0.14 | 0.02 | 0.31 | 0.01 | 0.00 |
| [1,5) | 0.01 | 1.45 | 0.43 | 0.02 | 0.02 | 0.02 | 0.47 | 0.18 | 0.01 |
| [5,12) | 0.00 | 0.18 | 5.17 | 0.40 | 0.05 | 0.07 | 0.72 | 0.40 | 0.00 |
| [12,14) | 0.00 | 0.01 | 0.62 | 5.57 | 1.38 | 0.07 | 0.86 | 0.48 | 0.01 |
| [14,18) | 0.01 | 0.03 | 0.07 | 0.46 | 6.21 | 0.64 | 0.76 | 0.52 | 0.00 |
| [18,25) | 0.00 | 0.03 | 0.04 | 0.01 | 0.42 | 2.02 | 0.36 | 0.20 | 0.00 |
| [25,45) | 0.00 | 0.05 | 0.18 | 0.02 | 0.07 | 0.10 | 0.27 | 0.09 | 0.00 |
| [45,70) | 0.00 | 0.06 | 0.15 | 0.04 | 0.12 | 0.05 | 0.11 | 0.10 | 0.01 |
| 70+ | 0.00 | 0.00 | 0.01 | 0.00 | 0.01 | 0.00 | 0.00 | 0.01 | 0.00 |
Based on comparing the diagonal elements for the school-aged children age groups, we have some basis for an assumption that 70% of a student’s within-age-group contacts occur at their own school:
schportion <- 0.70Now we use the above ingredients to create a new matrix using the
contactMatrixAgeSchool() function. We show the old
age-structured model and the new age-and-school-structured model for
comparison:
cmps <- contactMatrixAgeSchool(agelims, agepops, schoolagegroups, schoolpops, schportion)
knitr::kable(round(cmp,2), format = "markdown")| under1 | 1to4 | 5to11 | 12to13 | 14to17 | 18to24 | 25to44 | 45to69 | 70+ | |
|---|---|---|---|---|---|---|---|---|---|
| under1 | 0.42 | 0.72 | 0.57 | 0.09 | 0.21 | 0.32 | 2.11 | 1.14 | 0.13 |
| 1to4 | 0.18 | 2.98 | 1.52 | 0.16 | 0.24 | 0.49 | 3.28 | 1.89 | 0.35 |
| 5to11 | 0.08 | 0.87 | 8.79 | 0.82 | 0.46 | 0.46 | 3.35 | 1.88 | 0.37 |
| 12to13 | 0.04 | 0.32 | 2.86 | 7.98 | 2.50 | 0.57 | 2.77 | 2.22 | 0.47 |
| 14to17 | 0.05 | 0.24 | 0.80 | 1.25 | 9.67 | 2.21 | 2.71 | 2.51 | 0.37 |
| 18to24 | 0.05 | 0.28 | 0.46 | 0.16 | 1.26 | 5.72 | 3.68 | 2.87 | 0.37 |
| 25to44 | 0.11 | 0.66 | 1.17 | 0.28 | 0.54 | 1.29 | 5.72 | 3.83 | 0.61 |
| 45to69 | 0.05 | 0.32 | 0.55 | 0.18 | 0.42 | 0.84 | 3.20 | 4.27 | 0.96 |
| 70+ | 0.01 | 0.14 | 0.26 | 0.09 | 0.15 | 0.26 | 1.22 | 2.30 | 1.57 |
| under1 | 1to4 | 5to11s1 | 5to11s2 | 12to13s3 | 12to13s4 | 14to17s5 | 14to17s6 | 18to24 | 25to44 | 45to69 | 70+ | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| under1 | 0.42 | 0.72 | 0.28 | 0.28 | 0.04 | 0.04 | 0.11 | 0.11 | 0.32 | 2.11 | 1.14 | 0.13 |
| 1to4 | 0.18 | 2.98 | 0.76 | 0.76 | 0.08 | 0.08 | 0.12 | 0.12 | 0.49 | 3.28 | 1.89 | 0.35 |
| 5to11s1 | 0.08 | 0.87 | 7.47 | 1.32 | 0.41 | 0.41 | 0.23 | 0.23 | 0.46 | 3.35 | 1.88 | 0.37 |
| 5to11s2 | 0.08 | 0.87 | 1.32 | 7.47 | 0.41 | 0.41 | 0.23 | 0.23 | 0.46 | 3.35 | 1.88 | 0.37 |
| 12to13s3 | 0.04 | 0.32 | 1.43 | 1.43 | 6.79 | 1.20 | 1.25 | 1.25 | 0.57 | 2.77 | 2.22 | 0.47 |
| 12to13s4 | 0.04 | 0.32 | 1.43 | 1.43 | 1.20 | 6.79 | 1.25 | 1.25 | 0.57 | 2.77 | 2.22 | 0.47 |
| 14to17s5 | 0.05 | 0.24 | 0.40 | 0.40 | 0.63 | 0.63 | 8.22 | 1.45 | 2.21 | 2.71 | 2.51 | 0.37 |
| 14to17s6 | 0.05 | 0.24 | 0.40 | 0.40 | 0.63 | 0.63 | 1.45 | 8.22 | 2.21 | 2.71 | 2.51 | 0.37 |
| 18to24 | 0.05 | 0.28 | 0.23 | 0.23 | 0.08 | 0.08 | 0.63 | 0.63 | 5.72 | 3.68 | 2.87 | 0.37 |
| 25to44 | 0.11 | 0.66 | 0.59 | 0.59 | 0.14 | 0.14 | 0.27 | 0.27 | 1.29 | 5.72 | 3.83 | 0.61 |
| 45to69 | 0.05 | 0.32 | 0.27 | 0.27 | 0.09 | 0.09 | 0.21 | 0.21 | 0.84 | 3.20 | 4.27 | 0.96 |
| 70+ | 0.01 | 0.14 | 0.13 | 0.13 | 0.05 | 0.05 | 0.07 | 0.07 | 0.26 | 1.22 | 2.30 | 1.57 |