Distribute a total sample size across strata defined by a single
stratification variable, under a fixed total n, target CV, or budget.
When the design uses multiple stratification variables (e.g. region and
urbanicity), cross them into a single variable beforehand so that each row
of frame represents one unique stratum.
Usage
n_alloc(frame, ...)
# Default S3 method
n_alloc(
frame,
...,
domains = NULL,
n = NULL,
cv = NULL,
budget = NULL,
measures = NULL,
targets = NULL,
psu = NULL,
objective = NULL,
alloc = c("neyman", "optimal", "proportional", "power"),
unit_cost = NULL,
alpha = 0.05,
deff = 1,
resp_rate = 1,
df = NULL,
min_n_stratum = NULL,
alloc_q = 0.5,
fpc = c("unit", "stage", "none"),
plan = NULL
)
# S3 method for class 'svyplan_prec'
n_alloc(frame, ..., n = NULL, cv = NULL, budget = NULL)Arguments
- frame
For the default method: a stratum-level data frame describing the population you want to sample. Each row represents one stratum, a subgroup of the population defined by a stratification variable such as region, age group, or urbanicity. The values in this frame typically come from a census, a population register, or a previous survey. Any stratum table with the columns below works, including a pool summary carried back from an executed sample once the measure columns are added.
When a design stratifies by several variables at once (e.g. region \(\times\) urbanicity), cross them into a single variable before calling
n_alloc(e.g. withinteraction()) so that each row maps to exactly one population cell.When
measuresandtargetsare supplied,frameinstead describes atomic allocation strata for joint constrained allocation. It requires unique, non-missingstratumand positive finiteNcolumns. It may containunit_cost,max_weight,take_all, and complete domain classification columns named bytargets$domain. In that modesd,var,meanandpbelong inmeasuresinstead. Each row must be homogeneous for every domain classification used by a target. For a fixed-take two-stage design, also supply wholeN_psuandn_per_psu, plus positivecost_psuandcost_ssu. A three-stage design additionally requires wholeN_ssuandn_per_ssu, and positivecost_tsu.N_psuis the number of PSUs in the stratum. In three-stage mode,N_ssuis the aggregate number of SSUs across all PSUs in the stratum (not the number per PSU). Stage costs replaceunit_cost.Required columns:
NNumber of units (e.g. households, individuals) in each stratum. These are population counts, not sample sizes. Must be positive and finite.
sdorvar(legacy mode)A measure of how spread out the variable of interest is within each stratum. Provide exactly one:
sd: the stratum standard deviation (\(\sqrt{\text{variance}}\)), orvar: the stratum variance.
Both must be non-negative and finite. When all strata have equal variability (or variability is unknown), a constant column (e.g.
sd = 1) yields proportional-to-size allocation.
Optional columns:
stratumA label identifying each stratum (e.g.
"Urban","Rural"). If omitted, row numbers are used. Must be unique, or unique within each domain whendomainsis set.meanorpThe stratum population mean or proportion of the variable of interest. Required when solving for
cv, because the coefficient of variation is defined relative to the mean. Usemeanfor continuous variables andp(in \([0, 1]\)) for binary (yes/no) variables.unit_costPer-unit interviewing cost in each stratum (positive, finite). Set higher values for strata that are more expensive to reach. Defaults to 1 everywhere (equal cost).
max_weightMaximum allowed sampling weight \(N_h / n_h\). Caps how under-represented a stratum can be. Use
NAfor strata without a cap. It bounds the gross weight, the units drawn, not the response-adjusted \(N_h/(n_hr_h)\), which differs onceresp_ratevaries by stratum.take_allLogical (or 0/1). If
TRUE, every unit in the stratum is included, a census stratum. Useful for small strata whose total population is tiny enough to enumerate.deff,resp_ratePer-stratum design effect and expected response rate, for designs whose fieldwork differs across strata.
NAin either column falls back to the scalar argument. Thedeffandresp_ratearguments override these columns when given as vectors.
For
svyplan_precobjects: a precision result fromprec_alloc().- ...
Additional arguments passed to methods. Unused arguments are rejected.
- domains
Character vector of column names in
frameto treat as domain identifiers, orNULL(default) for no domains. All names must exist inframe. Domains define sub-populations that each contain one or more strata. Whencvis the target, precision is enforced within every domain (see Details).- n
Total sample size. Specify exactly one of
n,cv, orbudget.- cv
Target coefficient of variation (relative standard error). For example,
cv = 0.05means the standard error of the estimated population mean or total should be at most 5 percent of the estimate. Requiresmeanorpinframe. When domain columns are present, this target is enforced in each domain. Specify exactly one ofn,cv, orbudget.- budget
Total field budget. In the classic modes, specify exactly one of
n,cv, orbudget, andbudgetcaps the affordable allocation. In joint constrained allocation it must be accompanied byobjective: the allocation minimizes the priority-weighted relative variance of the objective components subject to the budget, every hard target intargets, and the stratum bounds. Supplyingbudgetwithoutobjectivein joint mode is an error, because the two readings are incompatible.- measures
Optional long data frame for joint constrained allocation, with one row per required
stratumand indicatorname. Each row must contain eitherpin[0, 1], ormeanand exactly one of non-negativesdorvar. Optional row-specificdeffandresp_ratevalues override the scalar arguments, andNAuses the scalar default. In fixed-take multistage mode,icc_psuis required andvar_ratio_psudefaults to 1. Three-stage mode also requiresicc_ssuand derivesvar_ratio_ssuasvar_ratio_psu * (1 - icc_psu)when it is absent, which is the value the variance decomposition implies. Stage parameters may instead be supplied as stratum defaults inframe, in which case non-missing measure-row values take precedence. Only rows selected by a target and its domain are value-validated. Unused rows are ignored after their non-empty, unique keys and frame-stratum membership are checked. Must be supplied withtargets.- targets
Optional long data frame with one precision requirement per row. It requires indicator
nameand exactly one positivecv,moe, orrmoe. Optionaldomainandlevelselect a frame domain (.overallandlevel = NAdenote the whole population),alphaoverrides the scalar value for MOE, andconstraintsupplies a stable unique identifier. Must be supplied withmeasures. Optional whenobjectiveandbudgetare given, which requests the best design a budget can buy with no hard precision requirement.- psu
Optional PSU register for certainty-aware allocation, one row per PSU, with
stratumandN, the count of ultimate units in that PSU. The PSU sizes must sum toframe$Nwithin each stratum. Optionalpsu_idis carried through and optionalcertaintyforces a PSU into the certainty part whatever its size. It is an alternative to the frame columnN_psu, which says only how many PSUs a stratum has, and requires the frame columnn_per_psuandmeasures$icc_psu. Joint constrained allocation only, and two stages only. See the certainty section under Details.- objective
Optional estimates whose priority-weighted relative variance is minimized among the allocations that meet
targetsand the budget. Either a character vector of indicator names (overall domain, equal priority) or a data frame withnameplus optionaldomain,level, non-negativepriority, andcomponentcolumns, using the same indicator-domain identifiers astargets. At least one priority must be positive. Priorities need not be normalized. Requiresbudgetand must be supplied withmeasures.- alloc
Allocation rule:
"neyman"(default),"optimal","proportional", or"power".- unit_cost
Optional scalar or length-
nrow(frame)vector of per-stratum unit costs, overridingframe$unit_cost. Not used with fixed-take multistage joint allocation, which requires stage costs.- alpha
Significance level, default 0.05.
- deff
Design effect multiplier (> 0). A scalar applies to every stratum. A length-
nrow(frame)vector gives one per stratum and overrides adeffcolumn inframe.- resp_rate
Expected response rate, in (0, 1]. Default 1. A scalar applies to every stratum. A length-
nrow(frame)vector gives one per stratum and overrides aresp_ratecolumn inframe. See the nonresponse section of svyplan-package for what this adjustment does and does not claim.- df
Degrees of freedom of the variance estimator the allocation will have, typically sampled PSUs minus strata, and available from
design_df(). It switches the quantile used to translate amoetarget in and to reportmoeout. Acvtarget carries no quantile and is unaffected.NULL(default) applies no adjustment.- min_n_stratum
Optional minimum sample size per stratum.
- alloc_q
Bankier power parameter, used only when
alloc = "power". Numeric scalar in \([0, 1]\). Atalloc_q = 1the allocation equals Neyman. Atalloc_q = 0it yields near-equal subnational CVs. Default 0.5.- fpc
Which finite population correction the variance carries in cluster allocation:
"unit"(default) for the ultimate-unit1 - n / Non the whole inflated variance,"stage"for the stage-by-stage correction, exact under the equal-size, equal-take variance-component model this path assumes, or"none"forn_cluster()'s with-replacement model."stage"requiresN_psu, andN_ssuas well at three stages. Refused outside cluster allocation and with apsuregister. See the correction section in Details.- plan
Optional
svyplan()object providing design defaults.
Value
A svyplan_n object with type = "alloc" and a stratum-level
allocation table in $detail (also available via as.data.frame()),
with columns:
stratum,N,sd,unit_costStratum identifiers and inputs carried over from the frame. In cluster mode
unit_costis the derived effective per-element costcost_psu / n_per_psu + cost_ssu(1 when no stage costs were given), whilesdstays the input stratum SD.nAllocated sample size (continuous).
n_intInteger allocation. In
nmode the requested total is preserved (bounded largest-remainder rounding), except under a fixed cluster take, where the take is held and the total moves to the nearest whole multiple of it instead. Incvmode each stratum is rounded up so the integer design meets the target. Inbudgetmode units are added by variance reduction per unit cost so the integer design stays within budget. Always inside the integerized bounds (ceiling(.lower),floor(.upper)). An error is raised when no integer allocation can satisfy them.weightDesign weight
N / n.n_effEffective sample size
n * resp_rate / deff..lower,.upperBounds applied to the stratum (from
min_n_stratum,max_weight,take_all,N_psu, orN)..bindingWhether the allocation sits on one of its bounds.
.bound_sourceWhich constraint produced the bound the allocation sits on, and
NAwhen it sits on none..psu_fracCluster mode with
N_psuonly: the share of the stratum's PSU universe the design selects,n_psu / N_psu..se,.moe,.rmoe,.cvPrecision of the stratum's own mean under the allocation, on the same scale as
mean(orp). Multiply.sebyNfor the stratum total..rmoeis.moeas a fraction of the stratum mean..cvand.rmoeareNAunless the frame suppliesmeanorp..shareThe stratum's share of the design variance of the overall mean. Sums to 1 and identifies where precision is actually being bought. It is
NAwhen the design variance is zero, which a census is, since no stratum then holds a share of nothing.take_all,meanPresent when take-all strata or stratum means were supplied.
n_per_psu,n_psuCluster mode only: the continuous per-stratum take and implied number of PSUs (
n / n_per_psu).n_psu_int,n_per_psu_intCluster mode only: the whole-unit field design (whole PSUs and whole takes), chosen so that
budgetdesigns stay within budget andcvdesigns meet the target. Heren_int = n_psu_int * n_per_psu_int.n_psu,n_psu_int,n_per_psu,n_per_ssuJoint fixed-take multistage mode: continuous and whole first-stage decisions and the fixed later-stage takes.
n_per_ssuis present only for three stages. Publicnremains in ultimate-unit units, son = n_psu * n_per_psufor two stages andn = n_psu * n_per_psu * n_per_ssufor three stages. The same exact identities hold forn_intandn_psu_int.
The result also carries an $operational list describing the integer
field design. In joint mode it contains total n, variable field cost,
the full target table in constraints, all_pass, and the number of
integer-repair additions. In legacy modes it also reports the applicable
aggregate se, moe, and cv. Top-level quantities describe the
continuous design, while as.integer() returns the operational total.
In fixed-budget objective mode the result adds $objective, one row per
component with its priority, relative variance .relvar, equivalent
.cv, weighted .contribution, and .share of the total, plus the scalar
$objective_value. $operational carries the same two fields for the
integer design together with budget_residual. $params$mode is
"budget_objective" rather than "targets", and $optimization adds the
budget, whether it binds, its residual, the local budget_sensitivity
(change in objective value per extra unit of budget), and the
epsilon-constraint objective_bound and its multiplier.
Details
Joint constrained allocation
Supplying both measures and targets requests a minimum-cost allocation
meeting every indicator-domain precision requirement at once, and adding
objective with budget asks instead for the best design that budget can
buy. This generalized mode is mutually exclusive with scalar n, cv,
budget, domains and an explicit alloc rule, because the target table
defines the constraints and the allocation is solved jointly. Its input
contract, its multistage variance model, its infeasibility messages and the
predict() frontier are on n_alloc-generalized.
For fieldwork, use $detail$n_int, not the analytical continuous n.
Fixed-take count columns are numeric vectors whose values are exact whole
numbers. The _int suffix denotes operational integer semantics rather
than R's 32-bit integer storage type. Result lists contain diagnostics and
are not promised as a long-term serialization format.
Building the frame
The frame is a data frame where each row is one stratum of
your target population. It summarizes what you know about each
subgroup before sampling. A typical workflow:
Identify strata from a census or register (e.g. provinces, urban/rural areas, age groups).
Look up
N: the population count per stratum.Estimate
sd: the standard deviation of your key variable within each stratum (from a pilot survey, a previous census, or expert judgement). If unknown, setsd = 1everywhere for proportional allocation.Add
meanorpif you want to solve for a target CV.
A minimal frame:
When a design stratifies by several variables (e.g. region \(\times\) urbanicity), cross them into one variable first:
This ensures that each row maps to exactly one population cell and that
the allocation formulas apply to the correct per-stratum N and sd pairs.
Cluster designs within strata
Adding a icc_psu column to the frame turns the allocation into a
stratified two-stage design (e.g. enumeration areas then
households within each stratum). Under the cluster variance model
the problem reduces to the element allocation above with the stratum
SD inflated to
sd * sqrt(var_ratio_psu * (1 + icc_psu * (n_per_psu * resp_rate - 1)))
and, when stage costs are given, a per-element cost of
cost_psu / n_per_psu + cost_ssu. The clustering penalty is paid on the
take that responds, n_per_psu * resp_rate, since a unit that does not
respond contributes no within-cluster observation. The cost is paid on
the gross take, since it is issued either way. The two coincide at
resp_rate = 1. The whole-cluster operational search reads the same
responding take, so a design it accepts is one the continuous reduction
also accepts. All solve modes, allocation
methods, and constraints work unchanged. The n, cv, and budget modes
keep their meanings.
Cluster-mode columns:
icc_psu(required): within-PSU homogeneity per stratum, e.g. fromvarcomp()withstrata.var_ratio_psu(optional, default 1): variance ratio per stratum.n_per_psu(optional): fixes the per-stratum take, in the operational whole-unit design as much as in the continuous one. AnyNAentries are replaced by the cost-optimal takesqrt(cost_psu / cost_ssu * (1 - icc_psu) / icc_psu). Holding the take is whatnmode gives up its exact total for. The stratum is fielded as a whole number of clusters of that size, so its element count lands on the nearest multiple.cost_psu,cost_ssu(together): per-PSU and per-element costs. These are required forbudgetmode or whenn_per_psuis not fixed. They replaceunit_cost, which is not allowed in this mode.N_psu(optional): the number of PSUs available in the stratum.
What N_psu does, and what it does not
N_psu is a feasibility constraint and nothing more. It caps the
allocation at N_psu * n_per_psu ultimate units and caps the whole-unit
design at N_psu clusters, matching the bound the fixed-take path
already applies. Leaving it out preserves the unbounded behaviour, in
which the allocation may ask for more PSUs than a stratum contains.
On its own it does not activate a first-stage finite population
correction. Under the default fpc = "unit" no factor keyed to the PSU
sampling fraction enters the variance, however large a share of the PSU
universe the design takes, and print() says so once that share is
appreciable. Supplying N_psu bounds the design. Asking for the
correction as well is what fpc = "stage" does.
So at n_psu == N_psu the default still carries between-PSU variance even
though every PSU has been selected. That is deliberately conservative
and is no longer a literal variance representation. For the same
reason, a target this path reports as unreachable at the PSU bound may
be reachable under a finite-population first stage, and the error says so
rather than claiming the precision is impossible. Under fpc = "stage"
the between-PSU component does reach zero there, and the whole variance
reaches zero only when every stage is enumerated.
Because taking every PSU leaves the within-PSU take in force, it does not
enumerate a stratum, and take_all is refused in cluster mode for the
same reason the fixed-take path refuses it.
Which correction the variance carries
fpc chooses, and the three choices are nested rather than arbitrary.
Write \(f_1\) for the PSU sampling fraction and \(f_2\) for the
within-PSU one, both measured on what responds. Under the equal-size,
equal-take variance-component model this path assumes, the two-stage
without-replacement variance corrects each component by its own stage:
$$V = (1-f_1)\frac{S_1^2}{a} + (1-f_2)\frac{S_2^2}{am}.$$
"unit"(default) applies the ultimate-unit1 - n / Nto the whole clustering-inflated variance, so the between-PSU component is attenuated by it too. Since \(n/N = f_1f_2\), that factor is at least as large as either exact one, so this overstates both components rather than either being understated. It is conservative against the exact without-replacement variance at every sampling fraction."stage"applies the expression above, and its three-stage analogue. It needsN_psu, andN_ssuas well at three stages. It is exact for that model and not beyond it: unequal PSU sizes, a size-proportional first stage, and stochastic rather than expected nonresponse each need a more general variance expression, so it is refused with apsuregister."none"applies no correction at any stage, which isn_cluster()'s model exactly. Use it to compare the two interfaces at a sampling fraction where the correction would otherwise separate them.
So none \(\ge\) unit \(\ge\) stage at every sampling fraction,
and the three coincide as the fractions vanish.
The default stays "unit" deliberately. "stage" is exact under that
model, but it buys the exactness by depending on the mean PSU size
\(M = N/N_{psu}\), which the with-replacement form does not
use at all. Under unequal PSU sizes that mean is a stand-in, and planners
usually know it less well than they know icc_psu and the take. Choose
"stage" when the PSU sizes really are close to equal and the fractions
are large enough to matter.
Note that the two fractions are controlled by different quantities.
\(f_1\) falls as the design takes a smaller share of the PSU universe,
but \(f_2\) is the realized take over \(M\) and does not move with N
at all. A large population reached through a few large PSUs leaves
\(f_2\) wherever it was, so "stage" is not in general a small
correction to "none".
fpc is refused outside cluster allocation, where there are no stages to
choose between and the correction is always 1 - n / N.
Because icc_psu already accounts for the clustering, leave
deff at 1 unless it captures a different source of design
effect (e.g. weighting loss). A clustering deff on top of
icc_psu would double-count. The constraints min_n_stratum and
max_weight stay in element units. For fielding,
use the whole-unit design in n_psu_int and n_per_psu_int
(n_int = n_psu_int * n_per_psu_int). Its actual field cost and
precision are reported in $operational and, in budget mode,
never exceed the budget.
Certainty PSUs from a register
N_psu gives only the number of PSUs in a stratum. Supply psu to give
their sizes instead. It has one row per PSU with stratum and N, and the
sizes must sum to frame$N in every stratum. This two-stage joint-allocation
mode requires n_per_psu in frame and icc_psu in measures.
With take \(b_h\) and sampling fraction \(f_h = n_h / N_h\), a PSU is certain when its size reaches
$$N_{hi} \ge b_h / f_h.$$
The certainty part has no first-stage sampling variance. The remainder has
the usual clustering component, and the two are combined into the
anticipated design effect. psu$certainty can add a PSU to the certainty
part. It cannot remove a PSU above the threshold.
The threshold and allocation determine each other, so the solver iterates.
$optimization$certainty records whether it converged, cycled, or reached
its iteration limit. $detail gives the split and threshold by stratum,
while $psu gives each PSU's classification, its source, and n_take,
the take the operational design fields in it. A certainty PSU carries its
own whole take at the stratum rate, capped at its size, and a remainder
PSU carries n_per_psu. The takes are the operational design's own
numbers, so sum(n_take[certainty]) = n_certain_int in every stratum.
A fit solved with a register keeps it in $params$psu. Its presence is
the stable test for a certainty-aware fit, and it's possible to key on it
rather than on $detail column names.
The operational design is fieldable: certainty PSUs use their whole take
at the stratum rate and the remainder uses whole PSUs at n_per_psu. Thus
n_int = n_certain_int + n_psu_draw * n_per_psu in every stratum.
$operational reports the count, cost, and precision of that same design.
Use cost_psu and cost_ssu together to price PSU visits and interviews.
predict.svyplan can compare fixed values of n_per_psu.
Domains vs. strata
Domains are specified via the domains parameter. Domain columns
partition strata into sub-populations. Each domain groups
one or more strata. When cv is specified, the algorithm finds the
minimum total \(n\) such that the worst-case domain CV meets the
target, i.e. every domain achieves the required precision.
In n or budget mode, domains affect reporting only: per-domain
precision metrics appear in $domains but the allocation itself treats
all strata globally.
Allocation methods
Allocation is controlled by the alloc parameter (same methods as
strata_bound()):
proportional: \(n_h \propto N_h / r_h\)
neyman: \(n_h \propto N_h S_h \sqrt{d_h / r_h}\)
optimal: \(n_h \propto N_h S_h \sqrt{d_h / r_h} / \sqrt{c_h}\)
power: Bankier (1988), \(n_h \propto S_h N_h^{q}\sqrt{d_h/r_h}\), with exponent
alloc_q
The design effect \(d_h\) and response rate \(r_h\) enter only when they vary by stratum. A value shared by every stratum is a constant factor and cancels out of a proportional weighting, leaving the classical rules above it. The three variance-based rules carry \(\sqrt{d_h/r_h}\) because they minimize \(\sum W_h^2S_h^2d_h/(r_hn_h)\) against a constraint on the units drawn, which is what a budget pays for. Proportional carries \(1/r_h\) instead, and no \(d_h\) at all, because it is a count rule, not a variance optimum, and its purpose is a self-weighting sample, so it is the responding sample it holds proportional to \(N_h\).
Stratum allocations are rounded to integers using the ORIC method
(Cont and Heidari, 2015). Constraints (min_n_stratum, max_weight, take_all)
are enforced via recursive Neyman allocation (RNA, Wesolowski et al., 2021).
When budget is specified, the algorithm finds the maximum affordable
allocation under unit costs.
References
Valliant, R., Dever, J. A., & Kreuter, F. (2018). Practical Tools for Designing and Weighting Survey Samples (2nd ed.). Springer. Chapters 5 and 9.
Bankier, M. D. (1988). Power allocations: determining sample sizes for subnational areas. The American Statistician, 42(3), 174–177.
Bethel, J. (1989). Sample allocation in multivariate surveys. Survey Methodology, 15(1), 47–57.
Cont, R. and Heidari, M. (2015). Optimal rounding under integer constraints. arXiv preprint arXiv:1501.00014.
Wesolowski, J., Wieczorkowski, R. and Wojciak, W. (2021). Optimality of the recursive Neyman allocation. Journal of Survey Statistics and Methodology, 10(5), 1263–1275.
See also
n_alloc-generalized for the joint mode in full,
prec_alloc() for the inverse, strata_bound() for constructing the
strata to allocate over, and n_multi() for the unstratified
multi-indicator size that joint allocation refines.
Other stratified design functions:
n_alloc-generalized,
prec_alloc(),
strata_bound()
Examples
frame <- data.frame(
stratum = c("A", "B", "C"),
N = c(4000, 3000, 3000),
sd = c(10, 15, 8),
mean = c(50, 60, 55),
unit_cost = c(1, 1.5, 1)
)
n_alloc(frame, n = 600)
#> Stratum allocation (neyman, 3 strata)
#> field design: n = 600, cv = 0.0079, cost = 724
#> continuous optimum: n = 600, cv = 0.0079, se = 0.4305
#> (deff = 1)
#> design df = 597
n_alloc(frame, cv = 0.03)
#> Stratum allocation (neyman, 3 strata)
#> field design: n = 46, cv = 0.0294, cost = 56
#> continuous optimum: n = 44.23479, cv = 0.0300, se = 1.6350
#> (deff = 1)
#> design df = 43
frame_constraints <- transform(
frame,
max_weight = c(25, 20, NA),
take_all = c(FALSE, FALSE, TRUE)
)
n_alloc(frame_constraints, budget = 3500, alloc = "optimal", min_n_stratum = 40)
#> Stratum allocation (optimal, 3 strata)
#> field design: n = 3403, cv = 0.0076, cost = 3500
#> continuous optimum: n = 3403.425, cv = 0.0076, se = 0.4125
#> (min_n_stratum = 40, deff = 1)
#> design df = 401
frame_domains <- data.frame(
province = c("North", "North", "South", "South"),
stratum = c("Urban", "Rural", "Urban", "Rural"),
N = c(2000, 3000, 1800, 3200),
sd = c(12, 18, 10, 16),
mean = c(55, 48, 58, 50)
)
n_alloc(frame_domains, domains = "province",
cv = 0.04, alloc = "power", alloc_q = 0.3)
#> Stratum allocation (power, 4 strata)
#> field design: n = 112, cv = 0.0270, cost = 112
#> continuous optimum: n = 110.7422, cv = 0.0272, se = 1.4076
#> (deff = 1)
#> design df = 108
#> Domains: 2
#>
#> province .domain .n .se .moe .rmoe .cv .cost
#> North 5_North 59.23404 2.032000 3.982647 0.07839856 0.0400 59
#> South 5_South 51.50815 1.948447 3.818886 0.07221797 0.0368 52
# Joint targets for two indicators and an overlapping domain
joint_frame <- data.frame(
stratum = c("North urban", "North rural", "South urban"),
region = c("North", "North", "South"),
N = c(1000, 1800, 1200)
)
joint_measures <- data.frame(
stratum = rep(joint_frame$stratum, 2),
name = rep(c("coverage", "income"), each = 3),
p = c(0.5, 0.4, 0.6, NA, NA, NA),
mean = c(NA, NA, NA, 50, 55, 60),
sd = c(NA, NA, NA, 10, 12, 15)
)
joint_targets <- data.frame(
name = c("coverage", "income"),
domain = c(".overall", "region"),
level = c(NA, "North"),
cv = c(0.06, NA),
moe = c(NA, 3)
)
joint <- n_alloc(
joint_frame, measures = joint_measures, targets = joint_targets
)
prec_alloc(joint, n = joint$detail$n_int)
#> Joint allocation precision (2 constraints)
#> targets: all pass
# The best design a fixed budget can buy, subject to the same targets
bought <- n_alloc(
joint_frame, measures = joint_measures, targets = joint_targets,
objective = "income", budget = 4000
)
bought$objective
#> component name domain level priority .relvar .cv .contribution
#> 1 income@.overall income .overall <NA> 1 0 0 0
#> .share
#> 1 NA
# Unequal priorities, and an objective on a specific domain
priorities <- data.frame(
name = c("income", "coverage"),
domain = c(".overall", "region"),
level = c(NA, "North"),
priority = c(2, 1)
)
n_alloc(
joint_frame, measures = joint_measures, targets = joint_targets,
objective = priorities, budget = 4000
)
#> Joint constrained allocation (Bethel)
#> question: best design affordable within a budget of 4000
#> field design: n = 4000, cost = 4000 (2 targets, all pass)
#> continuous optimum: n = 4000, cost = 4000
#> objective: weighted relative variance 0 continuous, 0 operational
#> the budget is not binding: the allocation sits at its upper bounds
#>
#> component priority .cv .share
#> income@.overall 2 0 NA
#> coverage@region=North 1 0 NA
#>
#> active bounds: 0 lower, 3 upper
# What would other budgets buy? (cost-versus-objective frontier)
predict(bought, data.frame(budget = c(3000, 4000, 5000)))
#> budget n cost objective_value cv n_int cost_int .binding
#> 1 3000 3000 3000 3.907646e-06 0.001976777 3000 3000 TRUE
#> 2 4000 4000 4000 0.000000e+00 0.000000000 4000 4000 FALSE
#> 3 5000 4000 4000 0.000000e+00 0.000000000 4000 4000 FALSE
#> .feasible
#> 1 TRUE
#> 2 TRUE
#> 3 TRUE
# The same target tables with fixed two-stage takes
joint_frame$N_psu <- c(100, 150, 100)
joint_frame$n_per_psu <- c(8, 10, 12)
joint_frame$cost_psu <- c(300, 400, 450)
joint_frame$cost_ssu <- c(25, 30, 35)
joint_measures$icc_psu <- rep(c(0.03, 0.05, 0.08), 2)
joint_measures$var_ratio_psu <- 1
joint_cluster <- n_alloc(
joint_frame, measures = joint_measures, targets = joint_targets
)
joint_cluster$detail[, c("stratum", "n_psu_int", "n_per_psu", "n_int")]
#> stratum n_psu_int n_per_psu n_int
#> 1 North urban 11 8 88
#> 2 North rural 17 10 170
#> 3 South urban 11 12 132
# Fixed three-stage takes: PSUs, SSUs within PSU, ultimate units within SSU
joint_frame$N_ssu <- c(600, 1000, 750) # aggregate SSUs by stratum
joint_frame$n_per_ssu <- c(3, 4, 3)
joint_frame$cost_tsu <- c(5, 6, 7)
joint_measures$icc_ssu <- rep(c(0.10, 0.08, 0.12), 2)
joint_measures$var_ratio_ssu <- 1
joint_three <- n_alloc(
joint_frame, measures = joint_measures, targets = joint_targets,
min_n_stratum = 20
)
joint_three$detail[, c(
"stratum", "n_psu_int", "n_per_psu", "n_per_ssu", "n_int"
)]
#> stratum n_psu_int n_per_psu n_per_ssu n_int
#> 1 North urban 7 8 3 168
#> 2 North rural 9 10 4 360
#> 3 South urban 6 12 3 216
prec_alloc(joint_three, n = joint_three$detail$n_int)
#> Joint allocation precision (2 constraints)
#> targets: all pass
# Stratified two-stage design (EAs then households per stratum)
frame_cluster <- data.frame(
stratum = c("Urban", "Rural"),
N = c(50000, 150000),
sd = c(0.45, 0.48),
mean = c(0.35, 0.25),
icc_psu = c(0.03, 0.08),
cost_psu = c(300, 600),
cost_ssu = c(40, 60)
)
n_alloc(frame_cluster, cv = 0.05)
#> Stratum allocation (neyman, two-stage, 2 strata)
#> field design: n = 2021, n_psu = 171, cv = 0.0498, cost = 206500
#> continuous optimum: n = 1979.882, cv = 0.0500, se = 0.0138
#> (deff = 1)
#> design df = 169