The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

brood(): Vaccine Coverage Data Structures for All Study Designs

Pre-aggregated and cohort models including time-series for interrupted time series analysis

Overview

library(mudnester)

brood() constructs a brood_df object for vaccine coverage analysis. Unlike roost() which counts events over time, vaccine coverage requires an explicitly documented eligible-population denominator and a declared assessment window. brood() makes both explicit in every object it produces.

The output brood_df is designed for bowerbird::brood_plot().

Why “brood”?

A brood is the full clutch under a parent bird’s care – every egg counted, every hatchling tracked, none overlooked. The gap between the clutch and the hatchlings is not an absence; it is information.

Two population models

Model Use case Input
"pre_aggregated" Already-computed counts per stratum Summary data frame
"cohort" Record-level, one row per person Wide or long dose data

The "cohort" model covers single time-point snapshots, birth cohort designs with person-time, and time-series sweeps for interrupted time series analysis.


Model 1: Pre-aggregated denominator

Supply a data frame with n_vaccinated and n_eligible already computed. No per-person dose logic is performed.

cov_static <- brood(
  data.frame(
    stratum      = c("0-17", "18-49", "50-64", "65+"),
    n_vaccinated = c(480L,   3550L,   2370L,   1760L),
    n_eligible   = c(1000L,  5000L,   3000L,   2000L)
  ),
  denominator_notes = "ABS ERP 2024, Sunshine Coast LGA."
)
print(cov_static)
#>   stratum date vaccine_type dose_number n_vaccinated n_eligible person_time
#> 1    0-17 <NA>         <NA>        <NA>          480       1000          NA
#> 2   18-49 <NA>         <NA>        <NA>         3550       5000          NA
#> 3   50-64 <NA>         <NA>        <NA>         2370       3000          NA
#> 4     65+ <NA>         <NA>        <NA>         1760       2000          NA
#>   coverage reference_date intervention_period
#> 1     0.48           <NA>                <NA>
#> 2     0.71           <NA>                <NA>
#> 3     0.79           <NA>                <NA>
#> 4     0.88           <NA>                <NA>
#>                                  window_description
#> 1 Pre-aggregated: denominators supplied externally.
#> 2 Pre-aggregated: denominators supplied externally.
#> 3 Pre-aggregated: denominators supplied externally.
#> 4 Pre-aggregated: denominators supplied externally.
#> 
#> -- brood_meta --------------------------------------
#>  population_model : pre_aggregated 
#>  validity_days    : Inf (no expiry) 
#>  strata           : 4 
#>  coverage range   : 48% to 88% 
#>  window desc      : Pre-aggregated: denominators supplied externally. 
#>  denominator      : ABS ERP 2024, Sunshine Coast LGA.

Multi-vaccine product comparison

cov_multi <- brood(
  data.frame(
    stratum      = rep(c("18-49", "50-64", "65+"), each = 2),
    vaccine_type = rep(c("Moderna XBB.1.5", "Pfizer XBB.1.5"), 3),
    n_vaccinated = c(1800L, 1750L, 1100L, 1270L, 800L, 960L),
    n_eligible   = c(5000L, 5000L, 3000L, 3000L, 2000L, 2000L)
  ),
  vaccine_type_col  = "vaccine_type",
  denominator_notes = "AIR enrolled persons, SC HHS 2024."
)
print(cov_multi)
#>   stratum date    vaccine_type dose_number n_vaccinated n_eligible person_time
#> 1   18-49 <NA> Moderna XBB.1.5        <NA>         1800       5000          NA
#> 2   18-49 <NA>  Pfizer XBB.1.5        <NA>         1750       5000          NA
#> 3   50-64 <NA> Moderna XBB.1.5        <NA>         1100       3000          NA
#> 4   50-64 <NA>  Pfizer XBB.1.5        <NA>         1270       3000          NA
#> 5     65+ <NA> Moderna XBB.1.5        <NA>          800       2000          NA
#> 6     65+ <NA>  Pfizer XBB.1.5        <NA>          960       2000          NA
#>    coverage reference_date intervention_period
#> 1 0.3600000           <NA>                <NA>
#> 2 0.3500000           <NA>                <NA>
#> 3 0.3666667           <NA>                <NA>
#> 4 0.4233333           <NA>                <NA>
#> 5 0.4000000           <NA>                <NA>
#> 6 0.4800000           <NA>                <NA>
#>                                  window_description
#> 1 Pre-aggregated: denominators supplied externally.
#> 2 Pre-aggregated: denominators supplied externally.
#> 3 Pre-aggregated: denominators supplied externally.
#> 4 Pre-aggregated: denominators supplied externally.
#> 5 Pre-aggregated: denominators supplied externally.
#> 6 Pre-aggregated: denominators supplied externally.
#> 
#> -- brood_meta --------------------------------------
#>  population_model : pre_aggregated 
#>  validity_days    : Inf (no expiry) 
#>  strata           : 3 
#>  coverage range   : 35% to 48% 
#>  window desc      : Pre-aggregated: denominators supplied externally. 
#>  denominator      : AIR enrolled persons, SC HHS 2024.

Model 2: Cohort – single time point

One row per person in data. Use entry_date_col and one of the five assessment windows. Inputs come from starling::murmuration() in wide format.

set.seed(99)
n <- 120L
dialysis_cohort <- data.frame(
  patient_id          = paste0("D", seq_len(n)),
  dialysis_start_date = seq(as.Date("2022-01-01"), by = "week", length.out = n),
  dialysis_end_date   = seq(as.Date("2022-01-01"), by = "week", length.out = n) +
    sample(90:900, n, replace = TRUE),
  age_group           = sample(c("45-64","65-74","75+"), n, replace = TRUE,
                               prob = c(0.25, 0.45, 0.30)),
  vax_date_1          = as.Date(ifelse(
    sample(c(TRUE, FALSE), n, replace = TRUE, prob = c(0.65, 0.35)),
    as.character(seq(as.Date("2022-01-01"), by = "week", length.out = n) +
                   sample(-400:400, n, replace = TRUE)),
    NA_character_)),
  vax_type_1          = sample(c("Influenza","COVID-19",NA), n, replace = TRUE,
                               prob = c(0.5, 0.3, 0.2)),
  stringsAsFactors = FALSE
)

Window 2a: Vaccination status at exit

cov_exit <- brood(
  dialysis_cohort,
  data_format      = "wide",
  population_model = "cohort",
  vax_date_cols    = "vax_date_1",
  entry_date_col   = "dialysis_start_date",
  exit_date_col    = "dialysis_end_date",
  window           = "at_exit",
  stratum_col      = "age_group",
  denominator_notes = "Dialysis cohort SC HHS. At-exit = vaccinated by dialysis end date."
)
print(cov_exit)
#>   stratum n_vaccinated n_eligible person_time  coverage vaccine_type
#> 1   45-64            9         34          NA 0.2647059         <NA>
#> 2   65-74            8         45          NA 0.1777778         <NA>
#> 3     75+           11         41          NA 0.2682927         <NA>
#>   dose_number reference_date intervention_period
#> 1        <NA>           <NA>                <NA>
#> 2        <NA>           <NA>                <NA>
#> 3        <NA>           <NA>                <NA>
#>                           window_description
#> 1 Cohort: vaccinated at or before exit date.
#> 2 Cohort: vaccinated at or before exit date.
#> 3 Cohort: vaccinated at or before exit date.
#> 
#> -- brood_meta --------------------------------------
#>  population_model : cohort 
#>  window           : at_exit 
#>  validity_days    : Inf (no expiry) 
#>  strata           : 3 
#>  coverage range   : 17.8% to 26.8% 
#>  window desc      : Cohort: vaccinated at or before exit date. 
#>  denominator      : Dialysis cohort SC HHS. At-exit = vaccinated by dialysis end date.

Window 2b: Baseline (pre-entry) vaccination status

cov_pre <- brood(
  dialysis_cohort,
  data_format       = "wide",
  population_model  = "cohort",
  vax_date_cols     = "vax_date_1",
  vax_type_cols     = "vax_type_1",
  vax_target        = "Influenza",
  entry_date_col    = "dialysis_start_date",
  window            = "pre_entry",
  stratum_col       = "age_group",
  denominator_notes = "Dialysis cohort. Pre-entry = vaccinated before dialysis start."
)
print(cov_pre)
#>   stratum n_vaccinated n_eligible person_time   coverage vaccine_type
#> 1   45-64            3         34          NA 0.08823529         <NA>
#> 2   65-74            7         45          NA 0.15555556         <NA>
#> 3     75+           13         41          NA 0.31707317         <NA>
#>   dose_number reference_date intervention_period
#> 1        <NA>           <NA>                <NA>
#> 2        <NA>           <NA>                <NA>
#> 3        <NA>           <NA>                <NA>
#>                                   window_description
#> 1 Cohort: valid dose before cohort entry (baseline).
#> 2 Cohort: valid dose before cohort entry (baseline).
#> 3 Cohort: valid dose before cohort entry (baseline).
#> 
#> -- brood_meta --------------------------------------
#>  population_model : cohort 
#>  window           : pre_entry 
#>  validity_days    : Inf (no expiry) 
#>  vax_target       : Influenza 
#>  strata           : 3 
#>  coverage range   : 8.8% to 31.7% 
#>  window desc      : Cohort: valid dose before cohort entry (baseline). 
#>  denominator      : Dialysis cohort. Pre-entry = vaccinated before dialysis start.

Window 2c: Vaccination within 1 year of cohort entry

cov_post <- brood(
  dialysis_cohort,
  data_format       = "wide",
  population_model  = "cohort",
  vax_date_cols     = "vax_date_1",
  vax_type_cols     = "vax_type_1",
  vax_target        = "Influenza",
  entry_date_col    = "dialysis_start_date",
  window            = "post_entry_days",
  window_days       = 365L,
  stratum_col       = "age_group",
  denominator_notes = "Dialysis cohort. Post-entry window = 365 days from dialysis start."
)
print(cov_post)
#>   stratum n_vaccinated n_eligible person_time  coverage vaccine_type
#> 1   45-64            5         34          NA 0.1470588         <NA>
#> 2   65-74           10         45          NA 0.2222222         <NA>
#> 3     75+           12         41          NA 0.2926829         <NA>
#>   dose_number reference_date intervention_period
#> 1        <NA>           <NA>                <NA>
#> 2        <NA>           <NA>                <NA>
#> 3        <NA>           <NA>                <NA>
#>                                    window_description
#> 1 Cohort: valid dose within 365 days of cohort entry.
#> 2 Cohort: valid dose within 365 days of cohort entry.
#> 3 Cohort: valid dose within 365 days of cohort entry.
#> 
#> -- brood_meta --------------------------------------
#>  population_model : cohort 
#>  window           : post_entry_days 
#>  validity_days    : Inf (no expiry) 
#>  vax_target       : Influenza 
#>  strata           : 3 
#>  coverage range   : 14.7% to 29.3% 
#>  window desc      : Cohort: valid dose within 365 days of cohort entry. 
#>  denominator      : Dialysis cohort. Post-entry window = 365 days from dialysis start.

Window 2d: Post-intervention vaccination

cov_intervention <- brood(
  dialysis_cohort,
  data_format       = "wide",
  population_model  = "cohort",
  vax_date_cols     = "vax_date_1",
  vax_type_cols     = "vax_type_1",
  vax_target        = "Influenza",
  entry_date_col    = "dialysis_start_date",
  exit_date_col     = "dialysis_end_date",
  window            = "post_intervention",
  intervention_date = as.Date("2023-06-01"),
  stratum_col       = "age_group",
  denominator_notes = paste0(
    "Dialysis cohort. Post-intervention = vaccinated on or after 2023-06-01."
  )
)
print(cov_intervention)
#>   stratum n_vaccinated n_eligible person_time  coverage vaccine_type
#> 1   45-64            4         34          NA 0.1176471         <NA>
#> 2   65-74            6         45          NA 0.1333333         <NA>
#> 3     75+            7         41          NA 0.1707317         <NA>
#>   dose_number reference_date intervention_period
#> 1        <NA>           <NA>                <NA>
#> 2        <NA>           <NA>                <NA>
#> 3        <NA>           <NA>                <NA>
#>                           window_description
#> 1 Cohort: valid dose on or after 2023-06-01.
#> 2 Cohort: valid dose on or after 2023-06-01.
#> 3 Cohort: valid dose on or after 2023-06-01.
#> 
#> -- brood_meta --------------------------------------
#>  population_model : cohort 
#>  window           : post_intervention 
#>  validity_days    : Inf (no expiry) 
#>  vax_target       : Influenza 
#>  strata           : 3 
#>  coverage range   : 11.8% to 17.1% 
#>  window desc      : Cohort: valid dose on or after 2023-06-01. 
#>  denominator      : Dialysis cohort. Post-intervention = vaccinated on or after 2023-06-01.

Model 3: Cohort – birth cohort with person-time

Birth cohort is a special case of the cohort model. Set entry_date_col = "dob" and supply eligibility_days to define the age-based eligibility window. Person-time (days at risk from birth until vaccinated or window expired) is computed automatically.

set.seed(42)
n <- 200L
birth_records <- data.frame(
  baby_id    = paste0("B", seq_len(n)),
  dob        = seq(as.Date("2024-01-01"), by = "day", length.out = n),
  gestation  = sample(c("Term","Preterm"), n, replace = TRUE, prob = c(0.85, 0.15)),
  vax_date_1 = as.Date(ifelse(
    sample(c(TRUE, FALSE), n, replace = TRUE, prob = c(0.55, 0.45)),
    as.character(seq(as.Date("2024-01-01"), by = "day", length.out = n) +
                   sample(30:200, n, replace = TRUE)),
    NA_character_)),
  vax_type_1 = "nirsevimab",
  stringsAsFactors = FALSE
)
cov_birth <- brood(
  birth_records,
  data_format       = "wide",
  population_model  = "cohort",
  vax_date_cols     = "vax_date_1",
  vax_type_cols     = "vax_type_1",
  vax_target        = "nirsevimab",
  entry_date_col    = "dob",       # DOB is the cohort entry date
  eligibility_days  = 180L,        # eligible from birth until 6 months
  censor_date       = as.Date("2024-12-31"),
  stratum_col       = "gestation",
  denominator_notes = paste0(
    "SCPHU birth cohort 2024-01-01 to 2024-12-31. ",
    "Eligible = live births in SC LGA. ",
    "Eligibility window = 180 days from birth. ",
    "Administrative censor date = 2024-12-31."
  )
)
print(cov_birth)
#>   stratum n_vaccinated n_eligible person_time  coverage vaccine_type
#> 1 Preterm           13         29        4350 0.4482759         <NA>
#> 2    Term           95        171       23980 0.5555556         <NA>
#>   dose_number reference_date intervention_period
#> 1        <NA>           <NA>                <NA>
#> 2        <NA>           <NA>                <NA>
#>                           window_description
#> 1 Cohort: vaccinated at or before exit date.
#> 2 Cohort: vaccinated at or before exit date.
#> 
#> -- brood_meta --------------------------------------
#>  population_model : cohort 
#>  window           : at_exit 
#>  validity_days    : Inf (no expiry) 
#>  vax_target       : nirsevimab 
#>  strata           : 2 
#>  coverage range   : 44.8% to 55.6% 
#>  window desc      : Cohort: vaccinated at or before exit date. 
#>  denominator      : SCPHU birth cohort 2024-01-01 to 2024-12-31. Eligible = live births in SC LGA. Eligibility window = 180 days from birth. Administrative censor date = 2024-12-31.

The person_time column shows days at risk. coverage = proportion vaccinated among those who had at least one eligible day.


Model 4: Cohort – time series (interrupted time series analysis)

This is the backbone of brood(). Set time_series = TRUE and supply ts_start, ts_end, and ts_by to sweep window = "current_at_date" across monthly (or other) intervals automatically. Returns one row per stratum per time point – the right shape for bowerbird::brood_plot().

When intervention_date is supplied, an intervention_period column is automatically added, labelling each row as "Pre-intervention" or "Post-intervention".

set.seed(7)
n <- 120L
jak_cohort <- data.frame(
  patient_id          = paste0("P", seq_len(n)),
  entry_date_nominal  = as.Date("2000-01-01"),  # placeholder entry date
  age_group           = sample(c("18-49","50-64","65+"), n, replace = TRUE),
  vax_date_1          = as.Date(ifelse(
    sample(c(TRUE, FALSE), n, replace = TRUE, prob = c(0.45, 0.55)),
    as.character(as.Date("2024-01-01") + sample(0:730, n, replace = TRUE)),
    NA_character_)),
  vax_type_1          = "Shingrix",
  vax_date_2          = as.Date(ifelse(
    sample(c(TRUE, FALSE), n, replace = TRUE, prob = c(0.25, 0.75)),
    as.character(as.Date("2024-06-01") + sample(0:365, n, replace = TRUE)),
    NA_character_)),
  vax_type_2          = "Shingrix",
  stringsAsFactors = FALSE
)
cov_ts <- brood(
  jak_cohort,
  data_format       = "wide",
  population_model  = "cohort",
  vax_date_cols     = c("vax_date_1", "vax_date_2"),
  vax_type_cols     = c("vax_type_1", "vax_type_2"),
  vax_target        = "Shingrix",
  validity_days     = Inf,
  entry_date_col    = "entry_date_nominal",
  time_series       = TRUE,
  ts_start          = as.Date("2024-12-01"),
  ts_end            = as.Date("2026-06-01"),
  ts_by             = "month",
  intervention_date = as.Date("2025-12-01"),
  denominator_notes = "JAK-inhibitor cohort. Shingrix only, no expiry."
)
#> (*)> mudnester::brood() — time_series: 19 month time points from 2024-12-01 to 2026-06-01
print(cov_ts)
#>    stratum n_vaccinated n_eligible person_time  coverage reference_date
#> 1  Overall           33        120          NA 0.2750000     2024-12-01
#> 2  Overall           41        120          NA 0.3416667     2025-01-01
#> 3  Overall           47        120          NA 0.3916667     2025-02-01
#> 4  Overall           52        120          NA 0.4333333     2025-03-01
#> 5  Overall           55        120          NA 0.4583333     2025-04-01
#> 6  Overall           56        120          NA 0.4666667     2025-05-01
#> 7  Overall           59        120          NA 0.4916667     2025-06-01
#> 8  Overall           60        120          NA 0.5000000     2025-07-01
#> 9  Overall           61        120          NA 0.5083333     2025-08-01
#> 10 Overall           62        120          NA 0.5166667     2025-09-01
#> 11 Overall           67        120          NA 0.5583333     2025-10-01
#> 12 Overall           72        120          NA 0.6000000     2025-11-01
#> 13 Overall           73        120          NA 0.6083333     2025-12-01
#> 14 Overall           74        120          NA 0.6166667     2026-01-01
#> 15 Overall           74        120          NA 0.6166667     2026-02-01
#> 16 Overall           74        120          NA 0.6166667     2026-03-01
#> 17 Overall           74        120          NA 0.6166667     2026-04-01
#> 18 Overall           74        120          NA 0.6166667     2026-05-01
#> 19 Overall           74        120          NA 0.6166667     2026-06-01
#>    intervention_period vaccine_type dose_number
#> 1     Pre-intervention         <NA>        <NA>
#> 2     Pre-intervention         <NA>        <NA>
#> 3     Pre-intervention         <NA>        <NA>
#> 4     Pre-intervention         <NA>        <NA>
#> 5     Pre-intervention         <NA>        <NA>
#> 6     Pre-intervention         <NA>        <NA>
#> 7     Pre-intervention         <NA>        <NA>
#> 8     Pre-intervention         <NA>        <NA>
#> 9     Pre-intervention         <NA>        <NA>
#> 10    Pre-intervention         <NA>        <NA>
#> 11    Pre-intervention         <NA>        <NA>
#> 12    Pre-intervention         <NA>        <NA>
#> 13   Post-intervention         <NA>        <NA>
#> 14   Post-intervention         <NA>        <NA>
#> 15   Post-intervention         <NA>        <NA>
#> 16   Post-intervention         <NA>        <NA>
#> 17   Post-intervention         <NA>        <NA>
#> 18   Post-intervention         <NA>        <NA>
#> 19   Post-intervention         <NA>        <NA>
#>                                                                                                 window_description
#> 1  Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 2  Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 3  Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 4  Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 5  Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 6  Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 7  Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 8  Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 9  Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 10 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 11 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 12 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 13 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 14 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 15 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 16 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 17 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 18 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 19 Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01.
#> 
#> -- brood_meta --------------------------------------
#>  population_model : cohort 
#>  time_series      : TRUE
#>  time_series_by   : month 
#>  n_time_points    : 19 
#>  intervention     : 2025-12-01 
#>  validity_days    : Inf (no expiry) 
#>  vax_target       : Shingrix 
#>  strata           : 1 
#>  coverage range   : 27.5% to 61.7% 
#>  window desc      : Time series: monthly 'current_at_date' coverage from 2024-12-01 to 2026-06-01, intervention line at 2025-12-01. 
#>  denominator      : JAK-inhibitor cohort. Shingrix only, no expiry.

The result is 19 rows: one per month ( 19 time points) across 1 stratum (“Overall”). With stratum_col supplied, each stratum gets its own row at every time point.

Stratified time series

cov_ts_strat <- brood(
  jak_cohort,
  data_format       = "wide",
  population_model  = "cohort",
  vax_date_cols     = c("vax_date_1", "vax_date_2"),
  vax_type_cols     = c("vax_type_1", "vax_type_2"),
  vax_target        = "Shingrix",
  validity_days     = Inf,
  entry_date_col    = "entry_date_nominal",
  stratum_col       = "age_group",
  time_series       = TRUE,
  ts_start          = as.Date("2024-12-01"),
  ts_end            = as.Date("2026-06-01"),
  ts_by             = "month",
  intervention_date = as.Date("2025-12-01"),
  denominator_notes = "JAK-inhibitor cohort by age group. Shingrix only."
)
#> (*)> mudnester::brood() — time_series: 19 month time points from 2024-12-01 to 2026-06-01
cat("Rows:", nrow(cov_ts_strat),
    "= ", attr(cov_ts_strat, "n_time_points"), "months x",
    attr(cov_ts_strat, "n_strata"), "age groups\n")
#> Rows: 57 =  19 months x 3 age groups
print(head(cov_ts_strat[, c("stratum","reference_date","intervention_period",
                              "n_vaccinated","n_eligible","coverage")], 9))
#>   stratum reference_date intervention_period n_vaccinated n_eligible  coverage
#> 1   18-49     2024-12-01    Pre-intervention           12         35 0.3428571
#> 2   50-64     2024-12-01    Pre-intervention            8         45 0.1777778
#> 3     65+     2024-12-01    Pre-intervention           13         40 0.3250000
#> 4   18-49     2025-01-01    Pre-intervention           13         35 0.3714286
#> 5   50-64     2025-01-01    Pre-intervention           13         45 0.2888889
#> 6     65+     2025-01-01    Pre-intervention           15         40 0.3750000
#> 7   18-49     2025-02-01    Pre-intervention           16         35 0.4571429
#> 8   50-64     2025-02-01    Pre-intervention           15         45 0.3333333
#> 9     65+     2025-02-01    Pre-intervention           16         40 0.4000000
#> 
#> -- brood_meta --------------------------------------
#>  population_model : 
#>  strata           : 
#>  coverage range   : 17.8% to 45.7%

Passing to bowerbird::brood_plot()

All models return brood_df objects accepted by bowerbird::brood_plot(). The time-series output auto-detects as a line chart:

# Pre-aggregated: bar chart with target line
bowerbird::brood_plot(cov_static, target_line = 0.80,
                       title = "COVID-19 booster coverage by age group")

# Time series: line chart with vertical intervention line (auto-detected)
bowerbird::brood_plot(cov_ts,
                       title = "Monthly Shingrix coverage, JAK-inhibitor cohort")

# Stratified time series: one line per stratum
bowerbird::brood_plot(cov_ts_strat,
                       title = "Shingrix coverage by age group")

The denominator_notes requirement

Every brood() call should include denominator_notes documenting:

brood() stores these notes as a metadata attribute. print.brood_df() displays them and bowerbird::brood_plot() can use them as a plot caption.


Session info

sessionInfo()
#> R version 4.5.2 (2025-10-31 ucrt)
#> Platform: x86_64-w64-mingw32/x64
#> Running under: Windows 11 x64 (build 26100)
#> 
#> Matrix products: default
#>   LAPACK version 3.12.1
#> 
#> locale:
#> [1] LC_COLLATE=C                       LC_CTYPE=English_Australia.utf8   
#> [3] LC_MONETARY=English_Australia.utf8 LC_NUMERIC=C                      
#> [5] LC_TIME=English_Australia.utf8    
#> 
#> time zone: Australia/Brisbane
#> tzcode source: internal
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] dplyr_1.2.0     mudnester_0.7.8
#> 
#> loaded via a namespace (and not attached):
#>  [1] vctrs_0.7.1       cli_3.6.5         knitr_1.51        rlang_1.2.0      
#>  [5] xfun_0.56         otel_0.2.0        generics_0.1.4    jsonlite_2.0.0   
#>  [9] glue_1.8.0        htmltools_0.5.9   sass_0.4.10       rmarkdown_2.31   
#> [13] evaluate_1.0.5    jquerylib_0.1.4   tibble_3.3.1      fastmap_1.2.0    
#> [17] yaml_2.3.12       lifecycle_1.0.5   compiler_4.5.2    pkgconfig_2.0.3  
#> [21] rstudioapi_0.18.0 digest_0.6.39     R6_2.6.1          utf8_1.2.6       
#> [25] tidyselect_1.2.1  pillar_1.11.1     magrittr_2.0.4    bslib_0.10.0     
#> [29] tools_4.5.2       cachem_1.1.0

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.