Skip to contents

Power computed from a single guess at the contextual inputs – baseline rate, nuisance signal, covariate dependence – is fragile (Hancock & Feng, 2026). ape_robust() re-runs the power analysis over a scenario grid of those inputs and reports per-scenario power, the worst case, and (optionally) n_max: the sample size that reaches the target power in every scenario – the insurance-premium n.

Usage

ape_robust(
  dgp,
  n,
  claim = c("minimum", "detect", "equivalence"),
  sesoi = NULL,
  alpha = 0.05,
  conf = NULL,
  nsim = 800,
  seed = NULL,
  vary,
  pin = c("ape", "coefficients"),
  mode = c("power", "mde"),
  power = 0.8,
  grid_points = 3,
  nmax = TRUE,
  nmax_power = 0.9,
  se = c("model", "robust"),
  direction = NULL,
  separation = c("fail", "keep")
)

Arguments

dgp

A powerape_dgp after set_ape() or set_aie().

n

Total sample size of the simulated study.

claim

"minimum" (default), "detect", or "equivalence".

sesoi

Smallest effect size of interest, in APE units. Required for "minimum" and "equivalence"; optional for "detect" (if supplied, the outcome table is still broken out against it).

alpha

The claim's error rate (default 0.05): two-sided for "detect", one-sided for "minimum", TOST for "equivalence". May also be a sample-size rule: a function of n returning the error rate to use at that n, for example function(n) alphaN::alphaN(n, BF = 3), the Bayes-factor calibration of Wulff and Taylor (2024) that lowers alpha as n grows. The searching functions evaluate the rule at every candidate n, so ape_n() designs jointly over the pair (alpha(n), n); results store the rule and the level it produced.

conf

Optional override: the interval level used for the claim itself (1 - alpha for detection, 1 - 2 alpha otherwise). Supplying conf = 0.95 for a minimum-effect or equivalence claim reproduces the pre-1.8.0 behavior (one-sided error rate 2.5%).

nsim

Number of simulation replications.

seed

Optional seed (the caller's RNG state is preserved).

vary

Named list of scenario values for contextual inputs. Parametric route: baseline, signal, correlation (scalar); empirical route: baseline, signal. A length-2 element is expanded to grid_points equally spaced values; longer vectors are used as-is. Scenarios are the full factorial grid.

pin

"ape" (re-invert per scenario) or "coefficients" (hold coefficients, let the implied effect drift). Ignored in MDE mode, which always re-solves.

mode

"power" (default) reports power at the pinned effect per scenario; "mde" reports the minimum detectable effect per scenario via ape_mde() – the worst case is then the MDE largest in magnitude, answering "what is the smallest effect this design finds even under the least favorable contextual assumptions?".

power

Target power for MDE mode (default 0.80; unused in power mode).

grid_points

Grid size used to expand length-2 vary elements.

nmax

Run the n_max search (default TRUE; power mode only).

nmax_power

Target power for the n_max search (default 0.90, the default of ape_n()).

se

Standard errors for the exogenous cross-sectional routes: "model" (default, expected-information ML) or "robust" (heteroskedasticity-robust HC0 sandwich, as in the sandwich package). Panel designs always use unit-clustered SEs and IV designs the stacked method-of-moments robust sandwich; se is ignored there.

direction

MDE mode only: "positive" or "negative" search direction, as in ape_mde(); default: the sign of the base DGP's pinned effect.

separation

How simulated studies with separation in an identifying cell are scored: "fail" (default; counted as failed, as the field's reference analysis refuses them) or "keep" (retained with their degenerate Wald intervals). See the section 'Separation and sparse cells'.

Value

A powerape_robust object: scenarios (inputs, implied effect, power, MCSE, share of simulated studies with separation), the worst scenario, marginal mean power per input, and the n_max result (nmax, the ape_n() result in the scenario that sets it; nmax_scenario, that scenario's inputs; nmax_candidates, every scenario searched with its answer).

Details

Two pinning modes (DESIGN.md section 3.3):

  • pin = "ape" (default): the inversion is re-run in every scenario, so the true effect stays at the planning value and only the precision channel varies. Scenarios where the target is infeasible are reported as such, not dropped silently.

  • pin = "coefficients": the effect coefficients stay at their base-case values while the contextual calibration is redone; the implied true effect drifts and is reported per scenario. Claim-boundary guards are relaxed here on purpose – showing that a scenario collapses power is the point.

n_max. The insurance-premium n is the largest requirement across scenarios. Power at the user's n cannot rank the scenarios for that purpose – at a generous n every scenario's power is near 1 – so the scenarios are ranked by a criterion that does not saturate: the normal-approximation requirement implied by each scenario's simulated standard error and its effect's distance from the claim boundary. ape_n() then runs in the least favorable scenario and in any scenario within 5% of it on that criterion (up to three), and n_max is the largest confirmed answer. When the implied effect of a feasible scenario sits on or beyond the claim boundary (possible with pin = "coefficients"), no n reaches the target there, and n_max is not reported.

Examples

# \donttest{
d <- ape_dgp(focal = pa_var("treat", "binary", p = 0.5), baseline = 0.30)
d <- set_ape(d, target = 0.10)
ape_robust(d, n = 700, claim = "detect",
           vary = list(baseline = c(0.20, 0.40)),
           nsim = 300, seed = 1, nmax = FALSE)
#> powerape robustness sweep -- detect claim, APE, pin = ape
#>   n = 700, nsim = 300 per scenario, 3 scenario(s) over: baseline
#>   power range [0.773, 0.890]; worst scenario:
#>  baseline implied_effect     power       mcse separated
#>       0.4            0.1 0.7733333 0.02417222         0
#>   scenarios:
#>  baseline implied_effect     power       mcse separated
#>       0.2            0.1 0.8900000 0.01806470         0
#>       0.3            0.1 0.8466667 0.02080242         0
#>       0.4            0.1 0.7733333 0.02417222         0
# }