Skip to contents

cluster_by() specifies the sampling units (PSUs/clusters) for cluster or multi-stage sampling designs. Unlike stratify_by(), which defines subgroups to sample within, cluster_by() defines units to sample as a whole.

Usage

cluster_by(.data, ..., nest = TRUE)

Arguments

.data

A sampling_design object (piped from sampling_design(), add_stage(), or stratify_by()), before the stage's draw().

...

Clustering variable(s) specified as bare column names that identify the sampling units. In most cases this is a single variable (e.g., school_id, household_id).

nest

Whether cluster ids are read within the stage's strata. TRUE (the default) makes town 1 of county A and town 1 of county B two different units. FALSE declares the ids unique across the strata and refuses a frame where they repeat. Without stratify_by() at the stage, nest has no effect.

Value

A modified sampling_design object with clustering specified.

Details

cluster_by() is purely structural. It defines what to sample, not how. The selection method and sample size are specified in draw().

Cluster vs. stratification

  • Stratification (stratify_by()): Sample within each group. All groups represented in the sample

  • Clustering (cluster_by()): Sample groups as units. Only selected groups appear in sample

Multi-stage designs

In multi-stage designs, each stage typically has its own clustering variable:

  • Stage 1: Select schools (cluster_by(school_id))

  • Stage 2: Select classrooms within schools (cluster_by(classroom_id))

  • Stage 3: Select students within classrooms (no clustering, sample individuals)

Ids numbered within strata and parents

Many frames number units within the level above them: towns 1, 2, 3 in every county, households 1, 2, 3 in every enumeration area. A unit is identified by its own id together with the strata of its stage and the units that earlier stages selected.

  • Within earlier stages. A stage's units are always identified within the units of earlier stages, so classroom_id = 1 can appear in every school.

  • Within the stage's strata. With nest = TRUE, a stage's ids are read within its own strata, so stratify_by(county) |> cluster_by(town) selects towns as county and town pairs. When the ids already differ across strata the key stays as declared, and frames for later stages can link by it alone. When they repeat, the strata join the key, and a separate register for a later stage must then carry them too. The executed design prints the result as town (within county).

Nesting only uses the variables the design names. If town ids restart in every district but the stage is stratified by region alone, towns of different districts with the same id are merged into one unit. List each level the ids restart under, either as strata or in cluster_by(), for example cluster_by(district, town).

Set nest = FALSE when the ids are meant to be unique across strata. It then works as a check. A cluster coded into two strata, such as an enumeration area whose households were given different urban and rural codes, is refused instead of being split into two units with part of the rows each.

Order of operations

Within a stage, cluster_by() and stratify_by() are optional and come before draw(), in either order. draw() is required and closes the stage, so cluster_by() after it is refused. sampling_design() describes the stage grammar and why the order matters.

See also

sampling_design() for creating designs, stratify_by() for stratification, draw() for specifying selection, add_stage() for multi-stage designs

Other design specification: add_stage(), draw(), sampling_design(), selection_methods, stratify_by()

Examples

# Simple cluster sample: select 30 EAs
sampling_design() |>
  cluster_by(ea_id) |>
  draw(n = 30) |>
  execute(zwe_eas, seed = 123)
#> # A tbl_sample: 30 × 17
#> # Sampling:     1 stage | 30 units
#> # Weights:      3575 [3575, 3575]
#>    ea_id province          district ward_pcode urban_rural population households
#>  * <int> <fct>             <fct>    <chr>      <fct>            <int>      <int>
#>  1 40006 Harare            Epworth  ZW192304   Urban             1384        372
#>  2 87920 Harare            Harare   ZW192137   Urban              780        212
#>  3 33850 Harare            Harare … ZW192401   Urban              301         78
#>  4 18135 Manicaland        Buhera   ZW110122   Rural               98         21
#>  5 66047 Manicaland        Buhera   ZW110106   Rural               98         23
#>  6 60773 Manicaland        Chipinge ZW110303   Urban               78         18
#>  7 12448 Manicaland        Makoni   ZW110431   Rural              123         25
#>  8 28763 Manicaland        Makoni   ZW110402   Rural              117         27
#>  9 22483 Mashonaland Cent… Mazowe   ZW120426   Rural               86         22
#> 10 21237 Mashonaland Cent… Mount D… ZW120509   Rural              471        126
#> # ℹ 20 more rows
#> # ℹ 10 more variables: buildings <int>, women_15_49 <int>, men_15_49 <int>,
#> #   children_under5 <int>, area_km2 <dbl>, .weight <dbl>, .sample_id <int>,
#> #   .stage <int>, .weight_1 <dbl>, .fpc_1 <int>

# Stratified cluster sample: 10 EAs per urban/rural
sampling_design() |>
  stratify_by(urban_rural) |>
  cluster_by(ea_id) |>
  draw(n = 10) |>
  execute(zwe_eas, seed = 1)
#> # A tbl_sample: 20 × 17
#> # Sampling:     1 stage | 20 units
#> # Weights:      5362.5 [2415.9, 8309.1]
#>     ea_id province         district ward_pcode urban_rural population households
#>  *  <int> <fct>            <fct>    <chr>      <fct>            <int>      <int>
#>  1  85418 Harare           Harare   ZW192118   Urban              154         54
#>  2  86381 Harare           Harare   ZW192141   Urban              200         54
#>  3  18031 Manicaland       Buhera   ZW110120   Rural              119         27
#>  4  60099 Manicaland       Chimani… ZW110216   Urban              149         38
#>  5  90121 Manicaland       Mutasa   ZW110601   Urban              420        110
#>  6  37769 Mashonaland Cen… Mbire    ZW120809   Rural              214         53
#>  7  23994 Mashonaland Cen… Mount D… ZW120536   Urban              140         33
#>  8  20542 Mashonaland East Goromon… ZW130204   Urban              275         71
#>  9  32927 Mashonaland East Maronde… ZW130420   Urban              127         33
#> 10  85023 Mashonaland East Maronde… ZW132105   Urban              483        143
#> 11  38359 Mashonaland East Mutoko   ZW130718   Rural               80         20
#> 12  13702 Mashonaland West Chegutu  ZW140102   Rural               83         22
#> 13  78285 Mashonaland West Sanyati  ZW142818   Urban               92         26
#> 14  33156 Mashonaland West Zvimba   ZW140635   Urban              277         71
#> 15  29555 Masvingo         Bikita   ZW180128   Rural               88         19
#> 16  11817 Masvingo         Gutu     ZW180403   Rural               25          6
#> 17    653 Masvingo         Mwenezi  ZW180616   Rural               91         18
#> 18  77314 Matabeleland No… Binga    ZW150125   Rural               64         15
#> 19  61839 Matabeleland No… Nkayi    ZW150502   Rural               69         14
#> 20 103261 Matabeleland So… Gwanda   ZW160412   Rural               26          6
#> # ℹ 10 more variables: buildings <int>, women_15_49 <int>, men_15_49 <int>,
#> #   children_under5 <int>, area_km2 <dbl>, .weight <dbl>, .sample_id <int>,
#> #   .stage <int>, .weight_1 <dbl>, .fpc_1 <dbl>

# PPS cluster sample using households as measure of size
sampling_design() |>
  cluster_by(ea_id) |>
  draw(n = 50, method = "pps_brewer", mos = households) |>
  execute(zwe_eas, seed = 2026)
#> # A tbl_sample: 50 × 18
#> # Sampling:     1 stage | 50 units
#> # Weights:      2143.52 [180.37, 6935.86]
#>    ea_id province district    ward_pcode urban_rural population households
#>  * <int> <fct>    <fct>       <chr>      <fct>            <int>      <int>
#>  1   296 Bulawayo Bulawayo    ZW102103   Urban              164         45
#>  2  2173 Bulawayo Bulawayo    ZW102104   Urban              400        120
#>  3  2243 Bulawayo Bulawayo    ZW102104   Urban              229         69
#>  4 22871 Bulawayo Bulawayo    ZW102109   Urban              585        157
#>  5 23746 Bulawayo Bulawayo    ZW102118   Urban              524        146
#>  6 46259 Bulawayo Bulawayo    ZW102128   Urban              316         83
#>  7 47397 Bulawayo Bulawayo    ZW102120   Urban              124         32
#>  8 85838 Harare   Chitungwiza ZW192204   Urban              532        137
#>  9 88065 Harare   Epworth     ZW192303   Urban              527        139
#> 10 87300 Harare   Harare      ZW192143   Urban              427        109
#> # ℹ 40 more rows
#> # ℹ 11 more variables: buildings <int>, women_15_49 <int>, men_15_49 <int>,
#> #   children_under5 <int>, area_km2 <dbl>, .weight <dbl>, .sample_id <int>,
#> #   .stage <int>, .weight_1 <dbl>, .fpc_1 <int>, .certainty_1 <lgl>

# Town ids restart in every county: each county's town 1 is its own unit
towns <- data.frame(
  county = rep(c("A", "B"), each = 6),
  town = rep(1:3, times = 4),
  household = 1:12
)
sampling_design() |>
  stratify_by(county) |>
  cluster_by(town) |>
  draw(n = 2) |>
  execute(towns, seed = 1)
#> # A tbl_sample: 8 × 8
#> # Sampling:     1 stage | 4 units
#> # Weights:      1.5 [1.5, 1.5]
#>   county  town household .weight .sample_id .stage .weight_1 .fpc_1
#> * <chr>  <int>     <int>   <dbl>      <int>  <int>     <dbl>  <dbl>
#> 1 A          1         1     1.5          1      1       1.5      3
#> 2 A          2         2     1.5          2      1       1.5      3
#> 3 A          1         4     1.5          3      1       1.5      3
#> 4 A          2         5     1.5          4      1       1.5      3
#> 5 B          1         7     1.5          5      1       1.5      3
#> 6 B          3         9     1.5          6      1       1.5      3
#> 7 B          1        10     1.5          7      1       1.5      3
#> 8 B          3        12     1.5          8      1       1.5      3

# Two-stage cluster sample
zwe_frame <- zwe_eas |>
  dplyr::mutate(district_hh = sum(households), .by = district)

sampling_design() |>
  add_stage(label = "Districts") |>
    cluster_by(district) |>
    draw(n = 20, method = "pps_brewer", mos = district_hh) |>
  add_stage(label = "EAs") |>
    draw(n = 10) |>
  execute(zwe_frame, seed = 1234)
#> # A tbl_sample: 200 × 21
#> # Sampling:     2 stages | 200/107,250 units
#> # Weights:      528.97 [135.84, 881.23]
#>    ea_id province district ward_pcode urban_rural population households
#>  * <int> <fct>    <fct>    <chr>      <fct>            <int>      <int>
#>  1  1311 Bulawayo Bulawayo ZW102105   Urban              109         32
#>  2 48293 Bulawayo Bulawayo ZW102115   Urban              380         97
#>  3 47427 Bulawayo Bulawayo ZW102121   Urban              696        179
#>  4 46195 Bulawayo Bulawayo ZW102128   Urban              691        181
#>  5 46178 Bulawayo Bulawayo ZW102128   Urban              325         85
#>  6 22895 Bulawayo Bulawayo ZW102109   Urban              356         95
#>  7  2192 Bulawayo Bulawayo ZW102104   Urban              412        124
#>  8  8696 Bulawayo Bulawayo ZW102102   Urban              177         48
#>  9 20336 Bulawayo Bulawayo ZW102108   Urban              538        138
#> 10  2294 Bulawayo Bulawayo ZW102104   Urban               88         27
#> # ℹ 190 more rows
#> # ℹ 14 more variables: buildings <int>, women_15_49 <int>, men_15_49 <int>,
#> #   children_under5 <int>, area_km2 <dbl>, district_hh <int>, .weight <dbl>,
#> #   .sample_id <int>, .stage <int>, .weight_2 <dbl>, .fpc_2 <dbl>,
#> #   .weight_1 <dbl>, .fpc_1 <int>, .certainty_1 <lgl>