Skip to contents

Generates one row per acute flaccid paralysis (AFP) case, shaped like the cleaned POLIS case table (polished_afp) that rise-afg reads. Non-polio cases arise in each district and year at npafp_rate per 100,000 children under 15, and n_positive poliovirus cases are added in a few districts. Each case carries a date chain that runs in order from onset through notification, investigation, the two stool collections, dispatch and arrival at the laboratory, to the culture, intratypic differentiation (ITD) and headquarters results.

Usage

simulate_afp_cases(
  admin = simulate_admin_frame(),
  population = NULL,
  start_date = as.Date("2023-01-01"),
  end_date = as.Date("2024-12-31"),
  npafp_rate = 3,
  n_positive = 4L,
  positive_types = c("WPV 1", "cVDPV 2"),
  positive_type_probs = c(0.75, 0.25),
  positive_districts = 3L,
  positive_onset_margin_days = 60,
  share_adequate = 0.85,
  inadequate_mode_probs = c(late = 0.5, one_stool = 0.3, poor_condition = 0.2),
  share_pending = 0.1,
  share_lab_pending = 0.3,
  pending_decay_days = 90,
  share_compatible = 0.01,
  share_npev = 0.1,
  delay_means = c(onset_to_notify = 4, notify_to_invest = 1, invest_to_stool1 = 1,
    stool1_to_stool2 = 1, stool_to_sent = 1, sent_to_lab = 2, lab_to_culture = 14,
    culture_to_itd = 7, itd_to_hq = 2, late_extra = 5, onset_to_followup_extra = 10,
    last_dose_before_onset = 60),
  delay_size = 2,
  age_months_range = c(6, 179),
  pending_age_missing = TRUE,
  sexes = c("Male", "Female"),
  sex_probs = c(0.55, 0.45),
  opv_doses_mean = 5,
  zero_dose_share = 0.05,
  routine_dose_share = 0.4,
  ipv_share = 0.6,
  paralysis_sign_probs = c(asymmetric = 0.6, onset_fever = 0.6, rapid_progress = 0.7),
  classification_labels = c(npafp = "NPAFP", compatible = "COMPATIBLE", pending =
    "PENDING", lab_pending = "LAB PENDING"),
  culture_results = c(negative = "Negative", npev = "NPEV", poliovirus =
    "Suspected Poliovirus", not_received = "Not received in lab"),
  stool_conditions = c(good = "Good", poor = "Poor"),
  yes_no = c(yes = "Yes", no = "No"),
  followup_findings = c("No residual weakness/paralysis", "Residual weakness/paralysis",
    "Died before follow-up"),
  followup_finding_probs = c(0.6, 0.35, 0.05),
  surveillance_type = "AFP",
  clusters = c("CLUSTER A", "CLUSTER B"),
  nt_changes_mean = 8,
  detected_flag = "Yes",
  jitter_deg = 0.05,
  seed = 2L
)

Arguments

admin

A geography from simulate_admin_frame(). Default simulate_admin_frame().

population

A table from simulate_population() covering every year in the window. Default NULL, which holds the under-15 population of admin constant across years.

start_date, end_date

First and last day of onset. Defaults as.Date("2023-01-01") and as.Date("2024-12-31"). end_date is also the date the data are taken to be extracted.

npafp_rate

Non-polio AFP cases per 100,000 children under 15 per year. Default 3.

n_positive

Number of poliovirus-positive AFP cases. Default 4L.

positive_types

Virus labels a positive case can carry. Default c("WPV 1", "cVDPV 2").

positive_type_probs

Weights for positive_types. Default c(0.75, 0.25).

positive_districts

Number of districts the positive cases fall in, chosen with weight by population. Default 3L.

positive_onset_margin_days

Positive cases have onset at least this many days before end_date, so their results are in. Default 60.

share_adequate

Share of cases drawn to meet the stool adequacy standard. Default 0.85.

inadequate_mode_probs

Weights for how an inadequate case fails: a late first stool, a single stool, or a stool in poor condition. Default c(late = 0.5, one_stool = 0.3, poor_condition = 0.2).

share_pending

Share of cases pending classification at end_date. Default 0.1.

share_lab_pending

Share of the pending cases whose specimens have not reached the laboratory. Default 0.3.

pending_decay_days

How quickly the chance of being pending falls with time since onset, in days. Default 90.

share_compatible

Share of the classified non-polio pool labelled compatible. The non-polio rate is inflated to make room for them, so non-polio cases still follow npafp_rate. Default 0.01.

share_npev

Share of non-polio cases whose culture grew a non-polio enterovirus. Default 0.1.

delay_means

Mean delays in days, one for each named step: onset_to_notify, notify_to_invest, invest_to_stool1, stool1_to_stool2 (at least 1), stool_to_sent, sent_to_lab, lab_to_culture, culture_to_itd, itd_to_hq, late_extra (days past the 14-day window for a late first stool), onset_to_followup_extra (days past day 60 for the follow-up visit) and last_dose_before_onset. Default c(onset_to_notify = 4, notify_to_invest = 1, invest_to_stool1 = 1, stool1_to_stool2 = 1, stool_to_sent = 1, sent_to_lab = 2, lab_to_culture = 14, culture_to_itd = 7, itd_to_hq = 2, late_extra = 5, onset_to_followup_extra = 10, last_dose_before_onset = 60).

delay_size

Size parameter of the negative binomial each delay is drawn from; smaller values give longer tails. Default 2.

age_months_range

Lower and upper age in months. Default c(6, 179).

pending_age_missing

Whether pending cases carry no age, as POLIS records them. Default TRUE.

sexes, sex_probs

Sex labels and their weights. Defaults c("Male", "Female") and c(0.55, 0.45).

opv_doses_mean

Mean number of oral polio vaccine doses. Default 5.

zero_dose_share

Share of cases with no vaccine dose. Default 0.05.

routine_dose_share

Share of oral doses given in routine immunisation rather than campaigns. Default 0.4.

ipv_share

Share of dosed cases with one inactivated polio vaccine dose. Default 0.6.

paralysis_sign_probs

Chance that a case shows each clinical sign. A case with all three is a hot case, as the cleaning defines it. Default c(asymmetric = 0.6, onset_fever = 0.6, rapid_progress = 0.7).

classification_labels

Labels for cases that are not positive. Default c(npafp = "NPAFP", compatible = "COMPATIBLE", pending = "PENDING", lab_pending = "LAB PENDING").

culture_results

Final cell culture result labels. Default c(negative = "Negative", npev = "NPEV", poliovirus = "Suspected Poliovirus", not_received = "Not received in lab").

stool_conditions

Stool condition labels. Default c(good = "Good", poor = "Poor").

yes_no

Labels for the adequacy fields. Default c(yes = "Yes", no = "No").

followup_findings, followup_finding_probs

Findings at the 60-day follow-up and their weights. Defaults c("No residual weakness/paralysis", "Residual weakness/paralysis", "Died before follow-up") and c(0.6, 0.35, 0.05).

surveillance_type

Surveillance type of every case. Default "AFP".

clusters

Cluster names a wild positive can carry. Default c("CLUSTER A", "CLUSTER B").

nt_changes_mean

Mean nucleotide changes of a vaccine-derived positive. Default 8.

detected_flag

Value written in a raw detection field such as wild1 when the virus was found. Default "Yes".

jitter_deg

Largest offset of a case from its district centre, in decimal degrees. Default 0.05.

seed

Seed for the random draws. Default 2L. The caller's random state is left as it was.

Value

A tibble with one row per case. Dates are Date, interval columns (onset_to_notify and the like) are double and missing outside the range the cleaning allows, year_onset and month_onset are integer, age_months and the dose counts are double, and the follow-up flags, hot_case and virus_is_orphan are logical. Coded columns are character.

Details

A case whose notification falls after end_date has not yet been reported and is left out. Cases are then held pending classification until their culture result is due, and further cases are made pending, with recent onsets more likely, until share_pending of all cases are pending. A pending case has no result dates and, by default, no age, as POLIS records it. Among the pending cases, those whose specimens have not reached the laboratory are classified LAB PENDING. Stool adequacy is derived from the dates and conditions that result, with share_adequate of cases drawn to meet the standard.

Column names, the classification vocabulary and the interval columns follow how rise-afg reads polished_afp in 02_scripts/00_helper_functions/0i_pending_helpers.R, 0j_spi_helpers.R, 0zb_specimen_helpers.R and 0a_polis_helpers.R, and in 02_scripts/2c_indicators/2cvi_timeliness.R, 2ci_detections.R, 2cxl_detection_surveillance.R, 2cxxxiii_followup.R and 2cxxxvi_es_profiles.R. The pending labels match polis_pending_classes and the surveillance type matches pending_surveillance_type in 02_scripts/00_helper_functions/00_params.R. The final culture result vocabulary beyond Not received in lab, the sex labels and the follow-up findings are not fixed by that code and are chosen here.

Examples

admin <- simulate_admin_frame(n_provinces = 2, n_districts = 3)
cases <- simulate_afp_cases(admin, n_positive = 2)
dplyr::count(cases, classification_all)
#> # A tibble: 5 × 2
#>   classification_all     n
#>   <chr>              <int>
#> 1 LAB PENDING            2
#> 2 NPAFP                 25
#> 3 PENDING                1
#> 4 WPV 1                  1
#> 5 cVDPV 2                1