This article covers variance components, two- and three-stage cluster designs, design effects, and design degrees of freedom. See Getting started for the core sizing and precision workflow, and allocation for stratified and joint allocation.
Multistage cluster designs
For two-stage or three-stage designs, the question is not just “how many?” but “how many clusters and how many units per cluster?” The answer depends on the cost structure and the degree of clustering.
Variance components from frame data
If frame data with cluster identifiers is available,
varcomp() estimates between-cluster and within-cluster
variance components:
set.seed(1)
n_clust <- 80
n_hh <- 15
cluster_id <- rep(seq_len(n_clust), each = n_hh)
cluster_mean <- rnorm(n_clust, mean = 50, sd = 10)
expenditure <- cluster_mean[cluster_id] + rnorm(n_clust * n_hh, sd = 20)
frame <- data.frame(cluster = cluster_id, expenditure = expenditure)
vc <- varcomp(expenditure ~ cluster, data = frame)
vc
#> Variance components (2-stage)
#> varb = 0.0398, varw = 0.1700
#> icc = 0.1896
#> var_ratio = 1.0589
#> Unit relvariance = 0.1981
as.data.frame(vc)
#> stages varb varw icc var_ratio unit_relvar
#> 1 2 0.03976226 0.1699763 0.1895801 1.058885 0.1980749The icc value is the survey-planning measure of
homogeneity. It feeds directly into n_cluster() and the
cluster-planning mode of design_effect(). This
icc is not a generic mixed-model ICC:
varcomp() returns the bounded planning quantity from
Valliant, Dever, and Kreuter (2018), and that is the scale expected by
the cluster-planning functions. When icc is near 0, most
variation is within clusters, so the analytical cluster optimum tends to
favor many interviews in very few PSUs. When icc is near 1,
most variation is between clusters, so the optimum tends to favor very
few interviews in many PSUs. Both are degenerate boundary cases for the
closed-form optimizer, so n_cluster() rejects values
numerically too close to 0 or 1.
Optimal two-stage allocation
Given per-stage costs and the variance structure,
n_cluster() finds the allocation that either minimizes cost
for a target CV, or minimizes CV for a given budget:
# Minimize cost to achieve CV = 0.05
n_cluster(stage_cost = c(500, 50), icc = vc, cv = 0.05)
#> Optimal 2-stage allocation
#> field design: n_psu = 26 | n_per_psu = 7 -> total n = 182
#> cv = 0.0496, cost = 22100
#> continuous optimum: n_psu = 26.30386 | n_per_psu = 6.538208 (cv = 0.0500, cost = 21751)
#> design df = 25
# Maximize precision within a budget
n_cluster(stage_cost = c(500, 50), icc = vc, budget = 100000)
#> Optimal 2-stage allocation
#> field design: n_psu = 125 | n_per_psu = 6 -> total n = 750
#> cv = 0.0233, cost = 100000
#> continuous optimum: n_psu = 120.9321 | n_per_psu = 6.538208 (cv = 0.0233, cost = 100000)
#> design df = 124Passing icc = vc (the varcomp object) automatically
extracts icc, unit_relvar, and
var_ratio.
Three-stage designs
Add a third cost element and a second icc for three-stage designs:
n_cluster(
stage_cost = c(1000, 200, 20),
icc = c(0.01, 0.05),
cv = 0.05
)
#> Optimal 3-stage allocation
#> field design: n_psu = 13 | n_per_psu = 5 | n_per_ssu = 15 -> total n = 975
#> cv = 0.0500, cost = 45500
#> continuous optimum: n_psu = 13.46593 | n_per_psu = 4.974937 | n_per_ssu = 13.78405 (cv = 0.0500, cost = 45333)
#> design df = 12Response rate in cluster designs
A cluster design can lose units at more than one stage, and the two
losses are not interchangeable, so they are named for the stage they act
on. resp_rate_psu is the share of selected clusters that
can be worked at all: whole PSUs lost to insecurity, flooding, or an
inaccessible road. Losing a PSU removes its entire contribution, so it
deflates every variance term alike and the first-stage sample is
inflated by 1 / resp_rate_psu to cover it.
In budget mode, applying a response rate does not change the allocation because the budget constrains the design. The achieved CV worsens instead. In CV mode:
n_cluster(stage_cost = c(500, 50), icc = vc, cv = 0.05, resp_rate_psu = 0.90)
#> Optimal 2-stage allocation
#> field design: n_psu = 29 | n_per_psu = 7 -> total n = 203 (net: 183)
#> (resp_rate_psu = 0.90)
#> cv = 0.0495, cost = 24650
#> continuous optimum: n_psu = 29.22651 | n_per_psu = 6.538208 (cv = 0.0500, cost = 24168)
#> design df = 28Household or individual nonresponse is a different quantity acting at
a different stage, and each has its own argument:
resp_rate_ssu for second-stage units in a three-stage
design, and resp_rate for the ultimate units. Naming a
stage the design does not have is an error rather than a silently
ignored argument, because a dropped response rate plans a design with
none.
The three are not interchangeable. Losing whole PSUs deflates every variance term alike, whereas losing ultimate units shrinks the realized cluster and so changes the clustering penalty too. That is why the later-stage rates move the cost-optimal take while the PSU rate does not:
# a DHS-shaped design: EAs, households within EAs, one person per household
n_cluster(stage_cost = c(500, 100, 50), icc = c(0.02, 0.05), cv = 0.05,
resp_rate_psu = 0.95, resp_rate_ssu = 0.90, resp_rate = 0.85)
#> Optimal 3-stage allocation
#> field design: n_psu = 36 | n_per_psu = 4 | n_per_ssu = 6 -> total n = 864 (net: 628)
#> (resp_rate_psu = 0.95, resp_rate_ssu = 0.90, resp_rate = 0.85)
#> cv = 0.0497, cost = 75600
#> continuous optimum: n_psu = 35.40747 | n_per_psu = 3.689324 | n_per_ssu = 6.686246 (cv = 0.0500, cost = 74438)
#> design df = 35Sizes and costs stay gross: $n counts the units to issue
and $cost pays for them, while the variance reads what they
realize. Lumping the later rates into resp_rate_psu is
conservative but wrong, and the gap grows with the between-PSU
homogeneity.
Fixed overhead costs
The standard cost model is purely linear:
C = c1*n_psu + c2*n_psu*n_per_psu. Real surveys also have a
fixed overhead (training, infrastructure, setup). The
fixed_cost parameter adds this term:
C = C0 + c1*n_psu + c2*n_psu*n_per_psu. In budget mode,
only budget - fixed_cost is available for the variable
component, reducing n_psu while leaving the optimal n_per_psu/n_psu
ratio unchanged. In CV mode, all sample sizes stay the same and
fixed_cost is simply added to the total cost:
# Budget mode: fixed overhead reduces the allocatable budget
n_cluster(stage_cost = c(500, 50), icc = vc, budget = 100000, fixed_cost = 5000)
#> Optimal 2-stage allocation
#> field design: n_psu = 111 | n_per_psu = 7 -> total n = 777
#> cv = 0.0240, cost = 99350 (fixed: 5000)
#> continuous optimum: n_psu = 114.8855 | n_per_psu = 6.538208 (cv = 0.0239, cost = 100000)
#> design df = 110
# CV mode: same allocation, cost increases by fixed_cost
n_cluster(stage_cost = c(500, 50), icc = vc, cv = 0.05, fixed_cost = 5000)
#> Optimal 2-stage allocation
#> field design: n_psu = 26 | n_per_psu = 7 -> total n = 182
#> cv = 0.0496, cost = 27100 (fixed: 5000)
#> continuous optimum: n_psu = 26.30386 | n_per_psu = 6.538208 (cv = 0.0500, cost = 26751)
#> design df = 25The same parameter is available when n_cluster() sizes a
table of indicators.
Evaluating cluster allocations
prec_cluster() computes the achieved CV for any
allocation:
alloc <- n_cluster(stage_cost = c(500, 50), icc = vc, budget = 100000)
prec_cluster(alloc)
#> Sampling precision for 2-stage cluster
#> n_psu = 121 | n_per_psu = 7 -> total n = 847
#> cv = 0.0233
# Arbitrary allocation
prec_cluster(n = c(50, 12), icc = 0.05)
#> Sampling precision for 2-stage cluster
#> n_psu = 50 | n_per_psu = 12 -> total n = 600
#> cv = 0.0508Design effects
design_effect() builds the design effect you expect a
plan to produce, from the design features you are choosing. The
clustering component uses the same variance model as
n_cluster() and prec_cluster(), so the two
always agree:
design_effect(icc = 0.05, n_per_psu = 20)
#> Planning design effect: 1.9500Components are selected by the arguments you supply and multiply together. Unequal weighting comes from planned weights or from a planned allocation’s stratum sizes and takes, and the stratification gain (the only component that can fall below 1) from the stratum standard deviations and means:
frame <- data.frame(
N = c(50000, 120000), n = c(600, 400), sd = c(12, 20), mean = c(55, 48)
)
deff <- design_effect(icc = 0.05, n_per_psu = 20, strata = frame)
deff
#> Planning design effect: 2.6279The result is a plain number wherever one is expected, and
effective_n() is its mirror:
n_prop(p = 0.3, moe = 0.05, deff = deff)
#> Sample size for proportion (wald)
#> n = 848 (p = 0.30, moe = 0.050, deff = 2.63)
#> expected cases = 254.4
effective_n(deff, n = 1000)
#> [1] 380.5354You can also read the features off a plan you already built,
including an n_alloc() allocation:
design_effect(n_cluster(stage_cost = c(500, 50), icc = 0.05, cv = 0.05))
#> Planning design effect: 1.6392These are planning quantities. After data collection, compute the
design effect the sample actually achieved with
survey::svymean(..., deff = TRUE), which uses the realized
weights, strata, and clusters.
Multi-indicator multistage
For surveys with several indicators in a cluster design, hand
n_cluster() a table of indicators carrying
icc_psu columns, along with stage costs:
targets_ms <- data.frame(
name = c("stunting", "vaccination"),
p = c(0.25, 0.70),
cv = c(0.10, 0.08),
icc_psu = c(0.05, 0.02)
)
n_cluster(indicators = targets_ms, stage_cost = c(500, 50), budget = 80000)
#> Multi-indicator optimal allocation (2-stage)
#> field design: n_psu = 64 | n_per_psu = 15 -> total n = 960
#> worst cv = 0.0729, cost = 80000 (binding: stunting)
#> continuous optimum: n_psu = 67.27204 | n_per_psu = 13.78403 (cv = 0.0728, cost = 80000)
#>
#> name .n .cv_target .cv_achieved .binding
#> stunting 491.76043 0.10 0.0728 *
#> vaccination 84.08575 0.08 0.0241