Skip to contents

Goal

Recreate, in miniature, the simulation workflow using the package API. We compare:

  • SRS (stratified approximation)
  • ALSD simple
  • ALSD modelled (ADAM optimizer)

We use a small subset of the included zimbabwe_minisample to keep runtime light and make this vignette stable for CRAN.

Setup

library(activesampling)
library(dplyr)
set.seed(123)

data(zimbabwe_minisample)
# Keep a compact sample so the vignette runs fast
pop <- zimbabwe_minisample %>% slice(1:6000)
strata <- c("gender", "region")
outcome <- "fcs_insuff_flag"

Helper: run one method

run_one <- function(method, optimizer = "adam") {
  run_alsd_simulation(
    population_df = pop,
    strata_vars   = strata,
    outcome_var   = outcome,
    method        = method,
    initial_sample_size = 200,
    wave_size     = 150,
    total_budget  = 800,
    optimizer     = optimizer
  )
}

Run scenarios

res_srs   <- run_one("alsd_simple")
#> 
#> --- Wave 1 ---
#> Respondents collected: 0/800
#> 
#> --- Wave 2 ---
#> Respondents collected: 166/800
#> 
#> --- Wave 3 ---
#> Respondents collected: 257/800
#> 
#> --- Wave 4 ---
#> Respondents collected: 321/800
#> 
#> --- Wave 5 ---
#> Respondents collected: 376/800
#> 
#> --- Wave 6 ---
#> Respondents collected: 432/800
#> 
#> --- Wave 7 ---
#> Respondents collected: 483/800
#> 
#> --- Wave 8 ---
#> Respondents collected: 515/800
#> 
#> --- Wave 9 ---
#> Respondents collected: 547/800
#> 
#> --- Wave 10 ---
#> Respondents collected: 586/800
#> 
#> --- Wave 11 ---
#> Respondents collected: 623/800
#> 
#> --- Wave 12 ---
#> Respondents collected: 645/800
#> 
#> --- Wave 13 ---
#> Respondents collected: 663/800
#> 
#> --- Wave 14 ---
#> Respondents collected: 693/800
#> 
#> --- Wave 15 ---
#> Respondents collected: 717/800
#> 
#> --- Wave 16 ---
#> Respondents collected: 743/800
#> 
#> --- Wave 17 ---
#> Respondents collected: 771/800
#> 
#> --- Wave 18 ---
#> Respondents collected: 798/800
#> Termination reason: Expended budget
res_model <- run_one("alsd_modelled", optimizer = "adam")
#> 
#> --- Wave 1 ---
#> Respondents collected: 0/800
#> 
#> --- Wave 2 ---
#> Respondents collected: 172/800
#> 
#> --- Wave 3 ---
#> Respondents collected: 286/800
#> 
#> --- Wave 4 ---
#> Respondents collected: 388/800
#> 
#> --- Wave 5 ---
#> Respondents collected: 472/800
#> 
#> --- Wave 6 ---
#> Respondents collected: 541/800
#> 
#> --- Wave 7 ---
#> Respondents collected: 582/800
#> 
#> --- Wave 8 ---
#> Respondents collected: 623/800
#> 
#> --- Wave 9 ---
#> Respondents collected: 670/800
#> 
#> --- Wave 10 ---
#> Respondents collected: 704/800
#> 
#> --- Wave 11 ---
#> Respondents collected: 734/800
#> 
#> --- Wave 12 ---
#> Respondents collected: 767/800
#> 
#> --- Wave 13 ---
#> Respondents collected: 786/800
#> Termination reason: Expended budget

# Explicitly print summaries so they appear in the vignette output
print(utils::head(res_srs$summary))
#>   wave      method n_respondents y_estimate       error     deff varw
#> 1    1 alsd_simple           166  0.1867470 -0.02825301 1.162421   NA
#> 2    2 alsd_simple           257  0.1750973 -0.03990272 1.083352   NA
#> 3    3 alsd_simple           321  0.1869159 -0.02808411 1.052692   NA
#> 4    4 alsd_simple           376  0.1888298 -0.02617021 1.035171   NA
#> 5    5 alsd_simple           432  0.1898148 -0.02518519 1.015821   NA
#> 6    6 alsd_simple           483  0.1966874 -0.01831263 1.015635   NA
#>   y_estimate_weighted error_weighted
#> 1                  NA             NA
#> 2                  NA             NA
#> 3                  NA             NA
#> 4                  NA             NA
#> 5                  NA             NA
#> 6                  NA             NA
print(utils::head(res_model$summary))
#>   wave        method n_respondents y_estimate       error     deff varw
#> 1    1 alsd_modelled           172  0.1453488 -0.06965116 1.098585   NA
#> 2    2 alsd_modelled           286  0.1713287 -0.04367133 1.110264   NA
#> 3    3 alsd_modelled           388  0.1752577 -0.03974227 1.083303   NA
#> 4    4 alsd_modelled           472  0.1927966 -0.02220339 1.063895   NA
#> 5    5 alsd_modelled           541  0.1977819 -0.01721811 1.054310   NA
#> 6    6 alsd_modelled           582  0.1941581 -0.02084192 1.050989   NA
#>   y_estimate_weighted error_weighted
#> 1                  NA             NA
#> 2                  NA             NA
#> 3                  NA             NA
#> 4                  NA             NA
#> 5                  NA             NA
#> 6                  NA             NA
cat("\nTermination (SRS-like): ", res_srs$termination_reason, "\n")
#> 
#> Termination (SRS-like):  Expended budget
cat("Termination (ALSD modelled): ", res_model$termination_reason, "\n")
#> Termination (ALSD modelled):  Expended budget

Add a lightweight RDD/quota approximation (Random-Digit Dialing inspired)

res_rdd <- rdd_like(pop, strata, outcome, init = 200, wave = 150, budget = 800)
print(utils::head(res_rdd$summary))
#>   wave   method n_respondents y_estimate         error     deff
#> 1    1 rdd_like            36  0.2777778  0.0627777778 1.509521
#> 2    2 rdd_like            63  0.2539683  0.0389682540 1.434060
#> 3    3 rdd_like            84  0.2261905  0.0111904762 1.207472
#> 4    4 rdd_like           112  0.2142857 -0.0007142857 1.182797
#> 5    5 rdd_like           137  0.2043796 -0.0106204380 1.128968
#> 6    6 rdd_like           156  0.2115385 -0.0034615385 1.106415

Quick comparison

compare <- dplyr::bind_rows(
  dplyr::mutate(res_srs$summary,   scenario = "SRS-like"),
  dplyr::mutate(res_model$summary, scenario = "ALSD modelled (ADAM)"),
  dplyr::mutate(res_rdd$summary,   scenario = "RDD-like quota (Random-Digit Dialing)")
)

cmp <- compare %>%
  dplyr::select(scenario, wave, n_respondents, deff, error) %>%
  dplyr::arrange(scenario, wave)
print(utils::head(cmp))
#>               scenario wave n_respondents     deff       error
#> 1 ALSD modelled (ADAM)    1           172 1.098585 -0.06965116
#> 2 ALSD modelled (ADAM)    2           286 1.110264 -0.04367133
#> 3 ALSD modelled (ADAM)    3           388 1.083303 -0.03974227
#> 4 ALSD modelled (ADAM)    4           472 1.063895 -0.02220339
#> 5 ALSD modelled (ADAM)    5           541 1.054310 -0.01721811
#> 6 ALSD modelled (ADAM)    6           582 1.050989 -0.02084192

Notes

  • The simple path targets post-stratification proportions and caps against remaining availability.
  • The budget and wave sizes are chosen to mirror the legacy scripts qualitatively, not identically.

For a fuller walkthrough, see vignettes/walkthrough.Rmd and the paper-summary vignette.