Skip to contents

Evaluate a svyplan result at new parameter combinations. Returns a data frame with the varied parameters and resulting quantities, suitable for sensitivity analysis or plotting.

Usage

# S3 method for class 'svyplan_n'
predict(object, newdata, ...)

# S3 method for class 'svyplan_cluster'
predict(object, newdata, ...)

# S3 method for class 'svyplan_power'
predict(object, newdata, ...)

# S3 method for class 'svyplan_prec'
predict(object, newdata, ...)

Arguments

object

A svyplan object (svyplan_n, svyplan_cluster, svyplan_power, or svyplan_prec). For svyplan_prec, the types "proportion", "mean", "ratio", "change", "pooled" and "alloc" are supported. Types "cluster" and "multi", and the precision of a PSU register allocation, are not.

newdata

A data frame of parameter combinations to evaluate. Column names must be valid parameters for the object type (see Details). Parameters not in newdata stay at their original values from the object.

...

Additional arguments are not supported and produce an error.

Value

A data frame with newdata columns followed by result columns. The result columns depend on the object type:

  • svyplan_n: n, se, moe, cv, rmoe, except for a type = "change" result, which reports one size per occasion as n1 and n2 in place of n, and a joint constrained allocation, which reports the design and cost columns described under Details

  • svyplan_cluster: n_psu, n_per_psu, (opt. n_per_ssu), total_n, cv, cost

  • svyplan_power: n, power, effect

  • svyplan_prec: se, moe, cv, rmoe, except for an allocation. A classic allocation reports n (the total), se, moe, cv, rmoe and cost, with .max_domain_cv when it has domains. A joint allocation reports n, cost, objective_value and cv when it has an objective, .max_ratio (the largest achieved over target ratio), .n_fail and .feasible. Given a list column n, the total is total_n.

When newdata sets a target, cv, moe, rmoe or power, the achieved value is reported beside it as .cv_achieved, .moe_achieved, .rmoe_achieved or .power_achieved. It equals the target unless a floor such as min_cases or min_n_stratum binds and carries the precision past it. A result column that repeats an input set in newdata, such as n or n_per_psu, is not shown twice.

Details

Valid parameters for newdata by object type:

  • n_prop: p, moe, rmoe, cv, alpha, N, deff, resp_rate, eligibility_rate, eligible_per_unit, df, min_cases

  • n_mean: var, mu, moe, rmoe, cv, alpha, N, deff, resp_rate, eligibility_rate, eligible_per_unit, df

  • n_ratio: r, cv_num, cv_den, component_cor, moe, rmoe, cv, alpha, N, deff, resp_rate, eligibility_rate, df

  • n_change: moe, rmoe, cv, alpha, N, deff, resp_rate, eligibility_rate, df, ratio, overlap, overlap_cor, and change on the mean scale only, since two proportions determine it. The occasion variances are held at the values the result was built from, so vary the design rather than the estimand. Sweeping overlap and overlap_cor is what prices a rotation against a fresh sample each round.

  • n_pooled: moe, rmoe, cv, alpha, N, deff, resp_rate, eligibility_rate, df, mu on the mean scale, and occasions only where the overlap and correlation are flat across lags, a shaped profile being a statement about a horizon that changing the horizon would contradict. The lag profiles themselves cannot be varied, a grid row having nowhere to hold a vector.

  • n_cluster: cv, budget, unit_relvar, resp_rate, resp_rate_psu, resp_rate_ssu, eligibility_rate, eligible_per_unit, fixed_cost, the fixed sizes n_psu, n_per_psu and n_per_ssu, stage deltas (icc or icc_psu, plus icc_ssu for 3-stage), stage ratios (var_ratio or var_ratio_psu, plus var_ratio_ssu for 3-stage), and stage costs (cost_psu, cost_ssu, cost_tsu). For 2-stage designs, cost_tsu aliases cost_ssu.

  • power_prop: p1, p2, n, power, alpha, N, deff, alternative, overlap, overlap_cor, resp_rate, eligibility_rate, eligible_per_unit (excluding the solved-for parameter). Not supported for objects with vector n.

  • power_mean: effect, var, n, power, alpha, N, deff, alternative, overlap, overlap_cor, resp_rate, eligibility_rate, eligible_per_unit (excluding the solved-for parameter). Not supported for objects with vector n.

  • n_alloc (classic modes): n, cv, budget, alpha, deff, resp_rate, eligibility_rate, df, min_n_stratum, alloc_q. A joint constrained allocation varies other controls, described below.

  • power_did: effect, n, power, alpha, N, deff, resp_rate, eligibility_rate, eligible_per_unit, alternative, overlap, overlap_cor, ratio (excluding the solved-for parameter).

  • prec_prop: p, n, alpha, N, deff, resp_rate, eligibility_rate, eligible_per_unit, df. A result that solved for p varies the target it solved from, cv or rmoe, in place of p.

  • prec_mean: var, n, mu, alpha, N, deff, resp_rate, eligibility_rate, eligible_per_unit, df. A result that solved for mu varies cv in place of mu.

  • prec_ratio: r, n, cv_num, cv_den, component_cor, alpha, N, deff, resp_rate, eligibility_rate, df

  • prec_change: n for both occasions, or n1 and n2 for each (not both forms), alpha, N, deff, resp_rate, eligibility_rate, df, overlap, overlap_cor, and change on the mean scale.

  • prec_pooled: n, alpha, N, deff, resp_rate, eligibility_rate, df, and mu on the mean scale. Where the overlap is the same at every lag, also overlap and cor_decay. Where the correlation is, also overlap_cor. Where both are, also occasions.

  • prec_alloc: n, alpha, deff, resp_rate, eligibility_rate, df, and for a joint allocation eligible_per_unit. A number in n rescales the stratum sizes to that total and keeps their shares. A list column n gives each row its own stratum sizes, one per row of the frame, to compare allocations.

For svyplan_n objects, moe, rmoe, and cv are mutually exclusive in newdata. If one appears, that mode is used. If none appears, the original mode is preserved.

Similarly, for svyplan_cluster objects, cv and budget are mutually exclusive.

Multi-indicator (n_multi) and multi-indicator cluster results are not supported. Use the underlying single-indicator functions instead.

A joint constrained allocation (n_alloc() with measures and targets) varies two controls, and each grid row re-solves the stored problem.

A fixed-budget objective fit varies budget, tracing the cost-versus-objective frontier. A fixed-take multistage fit varies the takes, n_per_psu for a two-stage design and either n_per_psu or n_per_ssu for a three-stage one, tracing what the fieldwork decision costs. A scalar take applies to every stratum, so the per-stratum takes the fit was built from are replaced rather than scaled. Sweep them asymmetrically by editing frame and calling n_alloc() per point. Both controls may appear together on a budget-objective fit, one row per combination.

The result reports the continuous n and cost, the operational n_int and cost_int, and .feasible. A multistage fit adds the PSU counts n_psu and n_psu_int, and budget mode adds objective_value, its equivalent cv, and whether the budget binds. A row the solver cannot satisfy, a budget too small to fund the hard targets or a take that exceeds the stage populations, gives an all-NA row with .feasible = FALSE and a warning, so one infeasible point does not discard the rest of the grid. A take that is not a positive whole number is a malformed grid rather than an infeasible design point, and stops.

A certainty-aware fit (n_alloc() with psu) varies n_per_psu too, and reports n_psu_certain and n_psu_draw in place of the PSU counts. This is how the take is priced. It also sets the certainty threshold, so a larger take leaves fewer certainty PSUs and costs more sample, and the resulting cost curve has a minimum worth finding rather than assuming. Such a fit also varies certainty_cutoff, one value per row applied to every stratum, to price a relaxed certainty rule the same way, and n_psu_per_zone, with NA for no zones, to compare zone settings. A grid that varies n_psu_per_zone, or a fit with zones, adds n_zone. A register fit sized to an objective within a budget varies budget as well.

A register grid adds .status. It reads "optimal", "gap" or "limit" for a row with a plan, as $operational$status does, "infeasible" where no design exists, and "unknown" where the search stopped before finding one or the solve failed, a row whose .feasible is NA. In budget mode objective_value and cv are those of the field design. A row the node limit stopped with a worse plan than a lower budget's, or with none, takes that plan, which fits its budget, so the objective never worsens as the budget grows. Its status reads "limit".

Precision targets stay out of reach of the grid. A one-stage minimum-cost fit therefore has nothing to vary. Modify targets and call n_alloc() again.

If evaluation fails for a particular row (e.g. invalid parameter combinations), that row's result columns are NA and a warning is issued.

See also

plot.svyplan to draw a one-parameter grid, and confint.svyplan for the interval implied by a single result.

Examples

# Sensitivity of sample size to deff and response rate
x <- n_prop(p = 0.3, moe = 0.05, deff = 1.5)
predict(x, expand.grid(
  deff = seq(1, 3, 0.5),
  resp_rate = c(0.7, 0.8, 0.9)
))
#>    deff resp_rate         n         se  moe         cv      rmoe
#> 1   1.0       0.7  460.9751 0.02551067 0.05 0.08503558 0.1666667
#> 2   1.5       0.7  691.4626 0.02551067 0.05 0.08503558 0.1666667
#> 3   2.0       0.7  921.9501 0.02551067 0.05 0.08503558 0.1666667
#> 4   2.5       0.7 1152.4376 0.02551067 0.05 0.08503558 0.1666667
#> 5   3.0       0.7 1382.9252 0.02551067 0.05 0.08503558 0.1666667
#> 6   1.0       0.8  403.3532 0.02551067 0.05 0.08503558 0.1666667
#> 7   1.5       0.8  605.0298 0.02551067 0.05 0.08503558 0.1666667
#> 8   2.0       0.8  806.7064 0.02551067 0.05 0.08503558 0.1666667
#> 9   2.5       0.8 1008.3829 0.02551067 0.05 0.08503558 0.1666667
#> 10  3.0       0.8 1210.0595 0.02551067 0.05 0.08503558 0.1666667
#> 11  1.0       0.9  358.5362 0.02551067 0.05 0.08503558 0.1666667
#> 12  1.5       0.9  537.8042 0.02551067 0.05 0.08503558 0.1666667
#> 13  2.0       0.9  717.0723 0.02551067 0.05 0.08503558 0.1666667
#> 14  2.5       0.9  896.3404 0.02551067 0.05 0.08503558 0.1666667
#> 15  3.0       0.9 1075.6085 0.02551067 0.05 0.08503558 0.1666667

# A floor of 400 expected cases holds n at 1334 for any cv target above
# 0.042, so the achieved cv stays at 0.042 there
rare <- n_prop(p = 0.3, cv = 0.05, min_cases = 400)
predict(rare, data.frame(cv = c(0.03, 0.05, 0.08)))
#>     cv        n        se        moe .cv_achieved       rmoe
#> 1 0.03 2592.593 0.0090000 0.01763968     0.030000 0.05879892
#> 2 0.05 1333.333 0.0125499 0.02459735     0.041833 0.08199118
#> 3 0.08 1333.333 0.0125499 0.02459735     0.041833 0.08199118

# Power curve: how does power vary with sample size?
pw <- power_prop(p1 = 0.30, p2 = 0.35, n = 500, power = NULL)
predict(pw, data.frame(n = seq(100, 1000, 100)))
#>       n     power effect
#> 1   100 0.1175929   0.05
#> 2   200 0.1877131   0.05
#> 3   300 0.2581732   0.05
#> 4   400 0.3272968   0.05
#> 5   500 0.3938436   0.05
#> 6   600 0.4569385   0.05
#> 7   700 0.5160053   0.05
#> 8   800 0.5707088   0.05
#> 9   900 0.6209032   0.05
#> 10 1000 0.6665884   0.05

# Cluster design: sensitivity to icc (homogeneity)
cl <- n_cluster(stage_cost = c(500, 50), icc = 0.05, budget = 100000)
predict(cl, data.frame(icc = c(0.01, 0.03, 0.05, 0.10, 0.15)))
#>    icc     n_psu n_per_psu   total_n         cv  cost
#> 1 0.01  48.23430 31.464265 1517.6570 0.02931966 1e+05
#> 2 0.03  71.47587 17.981472 1285.2413 0.03427016 1e+05
#> 3 0.05  84.08997 13.784049 1159.1003 0.03760588 1e+05
#> 4 0.10 102.63340  9.486833  973.6660 0.04357388 1e+05
#> 5 0.15 114.10493  7.527727  858.9507 0.04800166 1e+05

# Allocation: how does the CV change with sample size?
frame <- data.frame(
  N    = c(4000, 3000, 3000),
  sd   = c(10, 15, 8),
  mean = c(50, 60, 55)
)
alloc <- n_alloc(frame, n = 600)
predict(alloc, data.frame(n = seq(200, 1000, 200)))
#>      n        se       moe          cv       rmoe cost
#> 1  200 0.7624828 1.4944388 0.013990510 0.02742090  200
#> 2  400 0.5332495 1.0451498 0.009784394 0.01917706  400
#> 3  600 0.4305191 0.8438019 0.007899432 0.01548260  600
#> 4  800 0.3685682 0.7223803 0.006762719 0.01325469  800
#> 5 1000 0.3257913 0.6385393 0.005977823 0.01171632 1000

# The precision of that allocation if the budget is cut or raised, the
# stratum shares held, then three candidate allocations side by side
fixed <- prec_alloc(alloc, n = alloc$detail$n_int)
predict(fixed, data.frame(n = c(450, 600, 750)))
#>     n        se       moe          cv       rmoe cost
#> 1 450 0.5013507 0.9826292 0.009199095 0.01802989  450
#> 2 600 0.4305193 0.8438023 0.007899437 0.01548261  600
#> 3 750 0.3817637 0.7482430 0.007004838 0.01372923  750
predict(fixed, data.frame(n = I(list(c(200, 200, 200),
                                     alloc$detail$n_int,
                                     c(100, 200, 300)))))
#>              n total_n        se       moe          cv       rmoe cost
#> 1 200, 200....     600 0.4442747 0.8707624 0.008151829 0.01597729  600
#> 2 220, 248....     600 0.4305193 0.8438023 0.007899437 0.01548261  600
#> 3 100, 200....     600 0.5174746 1.0142317 0.009494947 0.01860976  600

# The precision of a change between two rounds as the panel overlap
# and its correlation vary
ch <- prec_change(p = c(0.30, 0.36), n = 1000, overlap = 0.5,
                  overlap_cor = 0.6)
predict(ch, expand.grid(n = c(800, 1200), overlap_cor = c(0.4, 0.7)))
#>      n overlap_cor         se        moe        cv      rmoe
#> 1  800         0.4 0.02098853 0.04113675 0.3498088 0.6856126
#> 2 1200         0.4 0.01713706 0.03358802 0.2856176 0.5598003
#> 3  800         0.7 0.01892173 0.03708591 0.3153621 0.6180984
#> 4 1200         0.7 0.01544953 0.03028052 0.2574921 0.5046753

# Two-stage joint allocation: what does the per-PSU take cost?
cluster_frame <- data.frame(
  stratum  = c("Urban", "Rural"),
  N        = c(60000, 40000),
  N_psu    = c(600, 500),
  n_per_psu = c(10, 10),
  cost_psu = c(400, 550),
  cost_ssu = c(20, 25)
)
cluster_measures <- data.frame(
  stratum = rep(cluster_frame$stratum, 2),
  name    = rep(c("literacy", "income"), each = 2),
  p       = c(0.62, 0.48, NA, NA),
  mean    = c(NA, NA, 520, 380),
  sd      = c(NA, NA, 210, 160),
  icc_psu = rep(c(0.04, 0.07), 2)
)
cluster_targets <- data.frame(
  name = c("literacy", "income"),
  cv   = c(0.03, 0.04)
)
joint <- n_alloc(cluster_frame, measures = cluster_measures,
                 targets = cluster_targets)
predict(joint, data.frame(n_per_psu = c(6, 10, 14, 20)))
#>   n_per_psu     n_psu        n      cost n_psu_int n_int cost_int .feasible
#> 1         6 175.97204 1055.832 103715.64       176  1056   103760      TRUE
#> 2        10 122.67192 1226.719  83273.41       123  1230    83400      TRUE
#> 3        14  99.75419 1396.559  76626.54       100  1400    76800      TRUE
#> 4        20  82.48407 1649.681  74400.37        83  1660    74650      TRUE