Social Mixing Matrices for Infectious Disease Modelling
Overview
Methods for sampling contact matrices from diary data for use in infectious disease modelling, as discussed in Mossong et al. (2008) doi:10.1371/journal.pmed.0050074.
New features
compute_matrix()gains abyargument that accepts any combination of participant/contact groupings, not just age. Each entry is either the string"age"(matching the columns produced byassign_age_groups()), a stem"<name>"(resolving topart_<name>andcnt_<name>), or an explicitc(part = "X", cnt = "Y")override. The result is a rank-2Karray where the firstKaxes index participants and the lastKindex contacts. The defaultby = "age"reproduces the single-grouping behaviour of previous releases.split_matrix()currently still requires a single-grouping matrix (#143).symmetrise()andper_capita()now accept multi-grouping matrices, with a singlesurvey_popformat across all groupings.survey_popis a data frame with one column per grouping, named after the grouping (e.g.age,gender) and holding that grouping's levels as they appear in the matrix, plus apopulationcolumn, with one row per combination. Levels are matched exactly: there is no interpolation.symmetrise()additionally requires the participant- and contact-side dims to share the same levels, otherwise reciprocity is undefined and it aborts (#319).
Show all changes in 0.7.0Hide the rest of the changes in 0.7.0
- New
rebin_ages()rebins a population table to a coarser set of age groups by summing. It operates on anagecolumn of age-group labels (as produced bylimits_to_age_groups()orassign_age_groups()) and returns the same form, so it composes directly with the post-processing functions. It only coarsens: requesting age groups finer than the population data is an error, since splitting a band would require assuming a within-band age distribution. - New
align_ages()aligns a population table to a contact matrix's groupings, returning thesurvey_popdata frame thatsymmetrise(),split_matrix()andper_capita()expect. Supply population with anagecolumn of age-group label, plus a column per other grouping;align_ages()coarsens age to the matrix's age groups within each combination of the other groupings (viarebin_ages()) and aggregates categorical groupings by exact name. The population must be at least as fine as the matrix's age groups. A typical workflow isresult |> symmetrise(survey_pop = align_ages(population, result))(#319). - The
contact_matrixS3 object now carries agroupingsfield — the list of grouping triples that produced itsmatrix. Used internally by the multi-grouping post-processing functions; users can read it to introspect the matrix's structure (#319). - New
flatten()returns aT x Tmatrix view of a multi-grouping contact matrix — Manna et al.'s generalised representation, with colon-joined dim labels (e.g."[0,5):F"). For single-grouping matrices it returns the matrix unchanged (#319). plot()andas.matrix()now work on multi-grouping contact matrices, operating on the flattenedT x Tview.matrix_plot()no longer assumes a square matrix, so non-square flattened matrices plot correctly (#321).- New vignette, *Contact matrices across more than one grouping*, with recipes for building, flattening, plotting and post-processing matrices over several groupings (#322).
weigh()gains a new canonical target shape: a two-column data frame whose key column matchesbyis joined and multiplied intoweight. This makes recipes likeweigh(survey, "country", target = ...)natural. The previous silent dispatch on a population data frame (atargetdata frame withlower.age.limit/populationand no column matchingby) is soft-deprecated; use the newweigh_by_age()for the same effect with an explicit name.weigh_by_age()takes a reference population with anagecolumn of age-group labels and apopulationcolumn. Newweigh_by_dayofweek()is a thin wrapper around the existing 5/2 split.weigh()'s named vector andgroupspaths are unchanged (#314).
Deprecations
- Exported function names now spell "age groups" consistently as
age_groups(snake_case), matchingassign_age_groups().reduce_agegroups(),limits_to_agegroups()andagegroups_to_limits()are renamed toreduce_age_groups(),limits_to_age_groups()andage_groups_to_limits(); the old names remain as deprecated aliases that warn (#331). - Interpolating population data to age groups finer than the data itself is deprecated.
contact_matrix()(when it adjusts demographic data to the requested age groups) andpop_age()still do it but now warn, and it will error in a future release. Supply population data at least as fine as the requested age groups. The newrebin_ages()andalign_ages()never interpolate: they error on finer requests. pop_age()is deprecated in favour ofrebin_ages()and warns; it will be removed in a future release (#328).- Advance deprecation cycle (#312).
wpp_age(),wpp_countries(), andsurvey_country_population()are deprecated (warn) — all three are thin layers overwpp2017, which is on its way out. Construct adata.framewith columnslower.age.limitandpopulationfrom a current source (e.g. thewpp2024package from GitHub) and pass it tocontact_matrix()viasurvey_popinstead. The implicit population lookup incontact_matrix()(whensurvey_popis not given butsymmetric,split,per_capita,weigh_age, orreturn_demographyis set) keeps the warning introduced in 0.6.0 with a sharper "will error in a future release" message.wpp2017remains inImportsfor now, so this lookup keeps working; it will move toSuggestsin a later release once reverse dependencies have migrated. The following are now defunct (deprecate_stop):survey(),check(),get_survey(),download_survey(),list_surveys(),survey_countries(),get_citation(), and themissing_contact_age = "sample"option onassign_age_groups()andcontact_matrix(). The dotted argument names (age.limits,survey.pop,country.column, etc.) oncontact_matrix(),pop_age(),clean(), andas_contact_survey()remain deprecated and warn, rather than becoming defunct, so downstream packages still using them keep working while they migrate. Bogus"1.0.0"versions on thesurvey()andcheck()deprecation messages have been corrected.
Bug fixes
load_survey()now errors clearly when given no files (e.g. an empty vector orNULLfrom a failed download) instead of raising an opaqueinvalid 'file' argument.
Internal
- Removed the air formatter:
air.toml, thestyle.yamlformat-suggestion workflow, and the VS Code formatter settings. lintr continues to run on changed files, andindentation_linteris re-enabled (with a hanging-indent style) to keep linting indentation now that air no longer handles it.
From NEWS.md in the release
Install
Health
- OK13 OK2026-08-04
- NOTE12 OK, 1 NOTE2026-08-01
- OK14 OK2026-03-10
Documentation
- Help pages
- 68 (37 internal)
- Examples that run
- 75%21 run in a plain check (3 of them under a condition) · 7 never run
- Exported functions with examples
- 84%
- Documented parameters
- 94%
- Return-value docs
- 97%
- Help pages citing references
- 1%
Downloads
Repository
- PRs merged (all time)
- 90%
- Median days to close, 50 most recently updated closed issues
- 30
- Median days to close, 50 most recently updated closed PRs
- 1
Stars over time
Forks over time
Releases over time
Issues over time
PRs over time
Commits over time
Commit identities over time
15 development-tooling and community-health practices detected across 8 families in the upstream repository
Checks run against github.com/epiforecasts/socialmixr on 2026-10-11.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-09-28 · The repository has a site deploy workflow
pkgdown site last built 2026-09-28
Show all practicesHide 4 practices
This repository shows signs of AI coding tools.
- Claude Codefirst seen 2025-12-05Seen in the repository: CLAUDE.mdNamed in .Rbuildignore: .claude, CLAUDE.local.md, CLAUDE.mdNamed in .gitignore: CLAUDE.local.mdPull request it wrote: opened by a project member
- CodeRabbitSeen in the repository: .coderabbit.yamlNamed in .Rbuildignore: .coderabbit.yaml
Dependencies
Installing socialmixr adds 37 packages (25 with compiled code, 33 MB of source tarballs). Heaviest: stringi 11 MB, data.table 5.7 MB, wpp2017 4.5 MB.
Code & Tests
Datasets
People & History
Pick two releases to compare their code metrics.
- 0.7.0Latest2026-04-29 · current release · diff ↗ ·
added 8 exports
age_groups_to_limits, align_ages, flatten, limits_to_age_groups, rebin_ages, reduce_age_groups, weigh_by_age, weigh_by_dayofweek - 0.6.02026-04-29 · diff ↗ ·
added 7 exports
agegroups_to_limits, compute_matrix, contact_age_distribution, per_capita, split_matrix, symmetrise, weigh - RR 4.6.0 released · 2026-04-24
- 0.5.12026-02-04 · diff ↗
- 0.5.02026-01-19 · diff ↗ ·
added 3 exports
as_contact_survey, assign_age_groups, survey_country_population - RR 4.5.0 released · 2025-04-11
- 0.4.0
- RR 4.4.0 released · 2024-04-24
- 0.3.22024-04-18 · diff ↗
- 0.3.12023-10-26 · diff ↗
- 0.3.0
- RR 4.3.0 released · 2023-04-21
- 0.2.0
- RR 4.2.0 released · 2022-04-22
- RR 4.1.0 released · 2021-05-18
- 0.1.82020-11-14 · diff ↗
Show 12 earlier eventsHide 12 earlier events
Package metadata
- First published
- 2018-01-08
- Total releases
- 18 / 8 yrs
- License
- MIT + file LICENSE OSI · relicensed from GPL-3 in 0.2.0
- Minimum R
- ≥ 4.1.0
- Bundled data
- 364 KB / 1 file
- Download size
- 604 KB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("socialmixr")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-18, which the citation names so these numbers can be found later. More on citing and the projects behind them.