Skip to contents

Manage extra doses across all administrative units across all the time periods (years or months).

Usage

handle_extra_doses(
  ri_data,
  ...,
  neighbors = NULL,
  max_level = 1,
  hed_assumption = "redistribute",
  in_place = FALSE,
  quiet = TRUE
)

Arguments

ri_data

[data.frame] Routine immunization data in the format required by impute_missing_doses(). Missing values are permitted only in vaccine-dose columns.

...

Forces optional arguments to be passed by name and allows for future extensions without breaking existing code. Must be empty.

neighbors

[list<character(1) = list<character>>] Named list specifying the list of neighboring administrative units by level for each administrative unit in the country shapefile. It is computed using get_neighbors().

max_level

[numeric(1)] Controls how far extra doses can be redistributed, specifying the maximum neighbor distance (in levels of adjacency) to consider. For example, if max_level = 1, only immediate neighbors are considered for redistribution. If max_level = 2, neighbors up to two levels away are considered.

hed_assumption

['redistribute' | 'discard' | 'scale'] Indicates the assumption to use to deal with extra doses. Options are:

  • 'redistribute' (default): Extra doses are redistributed proportionally (based on the number of unvaccinated children) to neighboring administrative units.

  • 'discard': Extra doses are discarded if they exceed the number of live births in the birth cohort.

  • 'scale': The number of live births is increased to match the number of available doses in case it is lower, assuming that the reported doses are accurate and the live births may be underestimated.

in_place

[logical(1)] If TRUE, modifies the ri_data input data in place if it is a data.table object. If FALSE (default), modifies its copy.

quiet

[logical(1)] If TRUE (default), suppresses warnings during the redistribution process. Otherwise, the function will print information, such as the total number of doses thrown away during the redistribution when hed_assumption = "redistribute".

Value

A data frame with extra doses handled. The columns are the same as the input ri_data.

Details

For each time point (year or month) and each specified dose, it computes the extra-doses as extra_doses = focus_dose - birth_cohort with birth_cohort, a numeric vector representing the number of babies born in a specific administrative unit and time.

The function handles extra doses based on the specified hed_assumption:

  • For hed_assumption = "redistribute", this function redistributes extra doses based to neighboring administrative units. To do that, extra doses are distributed to neighboring administrative units level by level:

    • Administrative units with surplus doses first attempt to allocate them to their immediate (first-level) neighbors.

    • If a neighbor cannot receive the full allocated share (e.g., the number of babies is insufficient), the maximum feasible number of doses is assigned, and the remaining surplus is carried forward to the next neighbor level.

    For each time point and vaccine dose, the redistribution process continues until one of the following conditions is met:

    1. All extra doses have been redistributed.

    2. No administrative units have remaining extra doses.

    3. No eligible recipient administrative units are available.

    4. The maximum neighbor level has been reached.

    This approach assumes the extra doses are due to migration of babies from neighboring administrative units.

  • For hed_assumption = "discard", this function discards extra doses for each administrative unit and time. This assumes that the reported doses are accurate and live birth data may be overestimated.

  • For hed_assumption = "scale", this function scales the number of live births to match the maximum number of doses across all vaccine doses for each administrative unit and time. This assumes that the reported doses are accurate and live birth data may be underestimated.

Examples

# Routine immunization data
ri_data <- tidyr::expand_grid(dist_code = c("D0", "D1", "D2", "D3", "D4"), year = 2015:2016) |>
  dplyr::mutate(
    VaxA0 = c(200, 500, 100, 400, 100, 300, 300, 500, 500, 500),
    VaxA1 = c(400, 400, 400, 400, 500, 500, 200, 100, 100, 100),
    VaxB1 = c(100, 500, 500, 200, 500, 100, 200, 300, 100, 300),
    VaxB2 = c(300, 100, 300, 500, 500, 200, 400, 400, 400, 100),
    live_births = c(100, 300, 200, 200, 200, 400, 400, 200, 100, 300)
  )
# Neighbourhood named list
neighbors <- list(
  D0 = list(c('D1', 'D2', 'D3'), 'D4'),
  D1 = list('D0', c('D2', 'D3'), 'D4'),
  D2 = list(c('D0', 'D4'), c('D1', 'D3')),
  D3 = list('D0', c('D1', 'D2'), 'D4'),
  D1 = list('D2', 'D0', c('D1', 'D3'))
)
## Neighbourhood is constructed from the following configuration
##    D1
##    D0 D3
## D4 D2

#' Deal with extra doses
handle_extra_doses(
  ri_data = ri_data,
  neighbors = neighbors,
  max_level = 3,
  hed_assumption = 'redistribute'
)
#>     dist_code  year VaxA0 VaxA1 VaxB1 VaxB2 live_births
#>        <char> <int> <num> <num> <num> <num>       <num>
#>  1:        D3  2015   333   400   400   400         400
#>  2:        D2  2015   133   200   200   200         200
#>  3:        D2  2016   400   400   400   400         400
#>  4:        D4  2016   300   300   300   200         300
#>  5:        D1  2016   200   200   200   200         200
#>  6:        D0  2015   100   100   100   100         100
#>  7:        D4  2015   100   100   100   100         100
#>  8:        D3  2016   200   200   200   200         200
#>  9:        D1  2015   133   200   200   200         200
#> 10:        D0  2016   300   300   300   300         300