Skip to contents

Verifies that two or more materialized waves come from one executed master and stacks them into a plain long table, one row per active master row per wave. This is the structural handoff to an inference layer. Which estimator of change is appropriate, and under what conditions, is a separate question that depends on the design and the overlap. See vignette("rotating-panels").

Row-binding waves by hand does not reproduce the checks this performs. Two executions of one design produce identical .sample_id values, so waves of different masters stack without complaint. A wave edited after execution keeps a correct provenance record while its rows no longer match it. Both are refused here.

Usage

stack_waves(...)

Arguments

...

Two or more materialized waves, each from execute(master, wave = t), all of one master realization.

Value

A tibble with wave, master_id, panel and design_weight first, then the columns of the waves themselves. One row per active master row per wave: under with-replacement selection a population unit may occupy several master rows, so a row is a selection occurrence rather than necessarily a distinct population unit. master_id is unique within a wave either way. It is an ordinary tibble, not a tbl_sample: it holds several realizations and repeats the unit key on purpose.

Details

What the columns mean

Four columns are generated, and their names are chosen to prevent the two substitutions that would quietly invalidate a downstream estimate:

wave

The wave each row was observed at.

master_id

A master-local unit key, taken from .sample_id. It matches units across waves of one master and means nothing outside it. It is not a population identity, and it is not generally a primary sampling unit: a clustered design's own cluster variable is carried through unchanged and is what a consumer's PSU argument wants.

panel

The rotation panel the row's assignment unit was given, or NA for a sample drawn without panels. That unit is the one the master's panel_stage names, so several rows can share one panel: all the members of a rotating household under a retained primary unit carry its label, not one of their own.

design_weight

samplyr's exact design weight for that wave, including the activation factor. It is not a final weight: nothing here is adjusted for nonresponse or calibrated, so a consumer asking for w_final is asking for something the analysis must supply.

Every other column of each wave is carried through unchanged, including the strata and cluster variables a consumer needs. samplyr's internal columns are dropped, stage-specific quantities such as .fpc_1 among them.

What it does not do

It does not compute a covariance, a correlation, or a variance of change. Those belong to the inference layer, and which estimator is appropriate depends on the overlap and the design. It does not reshape outcomes: attach each wave's measurement under a common name before stacking. It does not span cohorts of a rotation_program(), because identity across frame vintages is not established.

See also

execute() for materializing a wave, as_svydesign() for the per-wave export that supplies each wave's own variance, joint_expectation() with waves for how far two waves overlap

Other survey export: as_survey_design.tbl_sample(), as_survey_rep.tbl_sample(), as_svrepdesign(), as_svydesign()

Examples

rotation <- data.frame(
  panel = rep(1:4, times = 4),
  wave = rep(1:4, each = 4),
  active = c(
    TRUE, TRUE, FALSE, FALSE,
    FALSE, TRUE, TRUE, FALSE,
    FALSE, FALSE, TRUE, TRUE,
    TRUE, FALSE, FALSE, TRUE
  )
)

master <- sampling_design() |>
  draw(n = 40) |>
  execute(bfa_eas, seed = 2025, panels = rotation)

stack_waves(execute(master, wave = 1), execute(master, wave = 2))
#> # A tibble: 40 × 17
#>     wave master_id panel design_weight ea_id region province commune urban_rural
#>    <int>     <int> <int>         <dbl> <int> <fct>  <fct>    <fct>   <fct>      
#>  1     1         3     1         2228. 37130 Hauts… Tuy      Houndé  Rural      
#>  2     1         4     2         2228. 15678 Centre Kadiogo  Ouagad… Urban      
#>  3     1         6     2         2228. 11042 Boucl… Banwa    Tansila Rural      
#>  4     1         8     1         2228. 12542 Casca… Leraba   Dakôrô  Rural      
#>  5     1         9     2         2228.  8163 Centr… Koulpel… Ouarga… Rural      
#>  6     1        12     1         2228. 23664 Nord   Yatenga  Senguè… Rural      
#>  7     1        14     2         2228.   808 Centr… Boulgou  Bissiga Rural      
#>  8     1        15     1         2228. 15891 Centre Kadiogo  Ouagad… Urban      
#>  9     1        19     2         2228. 22755 Sahel  Oudalan  Markoye Rural      
#> 10     1        20     1         2228. 30483 Sahel  Seno     Dori    Rural      
#> # ℹ 30 more rows
#> # ℹ 8 more variables: population <int>, households <int>, area_km2 <dbl>,
#> #   pop_density <dbl>, longitude <dbl>, latitude <dbl>, remoteness <fct>,
#> #   fieldwork_cost <int>