svyplan helps you plan survey sample sizes, allocate a
sample across a design, and assess expected precision or power. You
supply anticipated outcome variability, design features, and response
assumptions. This vignette shows how to calculate a sample size, check
its precision, and compare planning assumptions.
The calculations describe a design before data collection. They do not select sample records or replace design-based analysis of the collected data.
Plan a coverage estimate
Suppose a survey must estimate vaccination coverage. A previous survey suggests that 70% of eligible people are vaccinated. The new survey should have a 95% confidence interval with a margin of error no greater than 5 percentage points.
Load the package and calculate the sample size:
library(svyplan)
coverage <- n_prop(p = 0.70, moe = 0.05)
coverage
#> Sample size for proportion (wald)
#> n = 323 (p = 0.70, moe = 0.050, deff = 1)
#> expected cases = 225.9Here p is the anticipated proportion and
moe is the desired interval half-width. The result keeps a
continuous calculation in $n. Printing and
as.integer() give the whole-unit sample to field:
c(
continuous = as.double(coverage),
fielded = as.integer(coverage)
)
#> continuous fielded
#> 322.6825 323.0000Use the whole-unit value for fieldwork. Keeping the continuous value inside the object avoids accumulating rounding differences when the result is passed to another calculation.
Add design and response assumptions
The first calculation assumes simple random sampling and complete response. Suppose earlier rounds suggest a design effect of 1.5 and an 85% response rate:
coverage <- n_prop(
p = 0.70,
moe = 0.05,
deff = 1.5,
resp_rate = 0.85
)
coverage
#> Sample size for proportion (wald)
#> n = 570 gross (net: 485) (p = 0.70, moe = 0.050, deff = 1.50, resp_rate = 0.85)
#> expected cases = 338.8The design effect increases the variance relative to simple random sampling. The response-rate adjustment increases the issued sample so the expected number of respondents meets the precision target. It assumes response is ignorable under the planned adjustment. It does not remove nonresponse bias or account for variation from response weights.
A finite population size can also be supplied with N.
The finite population correction matters when the planned sampling
fraction is appreciable:
n_prop(
p = 0.70,
moe = 0.05,
N = 5000,
deff = 1.5,
resp_rate = 0.85
)
#> Sample size for proportion (wald)
#> n = 520 gross (net: 442) (p = 0.70, moe = 0.050, deff = 1.50, resp_rate = 0.85)
#> expected cases = 309.0The single-stage n_*() and prec_*()
functions share these arguments:
| Argument | Meaning | Default |
|---|---|---|
deff |
Design effect multiplying the simple random sampling variance | 1 |
N |
Finite population size, which applies the finite population correction | Inf |
alpha |
Significance level of moe and
rmoe targets and of intervals |
0.05 |
resp_rate |
Expected response rate. The issued sample is the respondent sample divided by it | 1 |
Any deff > 0 is accepted. A design effect below 1
describes a design more efficient than simple random sampling, such as a
well-stratified sample. n_cluster() takes icc
and stage costs in place of deff and N, and
accepts a response rate for each stage.
Check expected precision
Every core n_*() function has a paired
prec_*() function. Passing the sample-size result carries
its assumptions into the precision calculation:
coverage_precision <- prec_prop(coverage)
coverage_precision
#> Sampling precision for proportion (wald)
#> n = 570 (net: 485)
#> se = 0.0255, moe = 0.0500, cv = 0.0364, rmoe = 0.0714
#> expected cases = 338.8
confint(coverage)
#> 2.5 % 97.5 %
#> 0.65 0.75The interval is the interval expected at the planning value of 70%.
It is not an interval estimated from survey data. Under the same method
and continuous design assumptions, passing the precision result back to
n_prop() recovers the original calculation:
n_prop(coverage_precision)
#> Sample size for proportion (wald)
#> n = 570 gross (net: 485) (p = 0.70, moe = 0.050, deff = 1.50, resp_rate = 0.85)
#> expected cases = 338.8Operational rounding and constrained allocations can make a fielded design slightly more precise than its continuous target. In those cases, assess the reported operational allocation rather than expecting exact numerical reversal.
Compare uncertain assumptions
Response rates and design effects are usually estimates.
predict() evaluates supported planning results at new
parameter combinations while holding the other assumptions fixed:
predict(
coverage,
expand.grid(
deff = c(1.2, 1.5, 2.0),
resp_rate = c(0.70, 0.85, 1.00)
)
)
#> deff resp_rate n se moe cv rmoe
#> 1 1.2 0.70 553.1701 0.02551067 0.05 0.03644382 0.07142857
#> 2 1.5 0.70 691.4626 0.02551067 0.05 0.03644382 0.07142857
#> 3 2.0 0.70 921.9501 0.02551067 0.05 0.03644382 0.07142857
#> 4 1.2 0.85 455.5518 0.02551067 0.05 0.03644382 0.07142857
#> 5 1.5 0.85 569.4398 0.02551067 0.05 0.03644382 0.07142857
#> 6 2.0 0.85 759.2530 0.02551067 0.05 0.03644382 0.07142857
#> 7 1.2 1.00 387.2190 0.02551067 0.05 0.03644382 0.07142857
#> 8 1.5 1.00 484.0238 0.02551067 0.05 0.03644382 0.07142857
#> 9 2.0 1.00 645.3651 0.02551067 0.05 0.03644382 0.07142857This grid shows the sample-size consequences of optimistic and
conservative assumptions. See ?predict.svyplan for the
parameters supported by each result class. For example, prediction from
a strata_bound() result assigns new observations to its
existing strata. It does not rerun a sensitivity grid.
Reuse shared assumptions
When several calculations use the same population and fieldwork assumptions, store them in a plan profile:
design <- svyplan(
deff = 1.5,
resp_rate = 0.85,
N = 5000
)
n_prop(p = 0.70, moe = 0.05, plan = design)
#> Sample size for proportion (wald)
#> n = 520 gross (net: 442) (p = 0.70, moe = 0.050, deff = 1.50, resp_rate = 0.85)
#> expected cases = 309.0
n_mean(var = 100, moe = 2, plan = design)
#> Sample size for mean
#> n = 165 gross (net: 141) (var = 100.00, moe = 2.000, deff = 1.50, resp_rate = 0.85)An explicit function argument overrides the corresponding profile value. This lets a common profile hold the defaults while an indicator supplies its own design effect or response rate:
n_prop(p = 0.70, moe = 0.05, plan = design, deff = 2)
#> Sample size for proportion (wald)
#> n = 673 gross (net: 572) (p = 0.70, moe = 0.050, deff = 2.00, resp_rate = 0.85)
#> expected cases = 400.2Profiles can also be piped into functions whose first argument accepts them:
design |> n_prop(p = 0.70, moe = 0.05)
#> Sample size for proportion (wald)
#> n = 520 gross (net: 442) (p = 0.70, moe = 0.050, deff = 1.50, resp_rate = 0.85)
#> expected cases = 309.0A profile can also carry cluster context. Stage costs and the
intraclass correlation stored in the profile are read by
n_cluster():
cluster_design <- svyplan(
stage_cost = c(500, 50),
icc = 0.05,
resp_rate = 0.85
)
n_cluster(cv = 0.05, plan = cluster_design)
#> Optimal 2-stage allocation
#> field design: n_psu = 52 | n_per_psu = 14 -> total n = 728 (net: 619)
#> (resp_rate = 0.85)
#> cv = 0.0500, cost = 62400
#> continuous optimum: n_psu = 49.9018 | n_per_psu = 14.9509 (cv = 0.0500, cost = 62255)
#> design df = 51Which function
Each row names a planning problem and the functions that address it.
The paired prec_ function evaluates precision under the
same sizing model.
| I want to size, or evaluate | Functions |
|---|---|
| a proportion, a mean or a ratio of two totals |
n_prop()/prec_prop(),
n_mean()/prec_mean(),
n_ratio()/prec_ratio()
|
| several indicators at once, taking the most demanding |
n_multi()/prec_multi()
|
| a two- or three-stage cluster design, for one indicator or a table of them |
n_cluster()/prec_cluster()
|
| an allocation across strata or domains, under a budget or a CV target |
n_alloc()/prec_alloc(),
strata_bound()
|
| a two-phase design that screens or follows up |
n_twophase()/prec_twophase()
|
| a change between two occasions of a repeated survey |
n_change()/prec_change()
|
| the average of several occasions of a repeated survey |
n_pooled()/prec_pooled()
|
| a panel that must still deliver a sample after attrition |
n_panel()/prec_panel()
|
| the overlap and field schedule a rotation pattern produces |
design_rotation(),
design_overlap(), design_schedule()
|
| the power of a two-group comparison or a difference-in-differences |
power_prop(), power_mean(),
power_did()
|
| the design effect, effective size or degrees of freedom of a plan |
design_effect(),
effective_n(), design_df(),
varcomp()
|
Sizing for a regression coefficient is not implemented, and there is
no n_reg(). The survey-specific part of that calculation,
the variance inflation from a complex design, is the deff
argument.
Choose the next guide
The package supports several estimands and design structures. The detailed guides below are available from the package website’s article index. Start from the question your plan must answer:
| Planning question | Continue with |
|---|---|
| Which precision target or interval method should I use? | Precision targets |
| How do several indicators or domains determine one sample? | Multiple indicators and domains |
| How should I construct strata or allocate a sample? | Stratification and allocation |
| How do I satisfy several allocation requirements together? | Joint allocation |
| How many clusters and units per cluster do I need? | Multistage surveys |
| How do I plan screening or nonresponse follow-up? | Two-phase surveys |
| How do overlap, attrition, and rotation affect repeated surveys? | Repeated surveys and panels |
| Can the design detect a group difference or change? | Power for comparisons and changes |
These advanced guides are website articles and require an internet connection when opened from the installed vignette. For household sampling, the analysis-to-listing-unit conversion explains how to translate a required person count into a household issue.
Sample-size planning depends on anticipated variances and on the sample design (Cochran 1977; Valliant, Dever, and Kreuter 2018). Treat those inputs as documented assumptions and revisit the plan when better information becomes available.