---
title: "Designing for a robust result"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Designing for a robust result}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4)
```

A trial is usually sized so that a true effect of a given size is significant with probability 0.8 or 0.9. The stress
test adds a second question: with what probability will that significant result also be **robust**, so that no
pre-specified alternative analysis or single deletion moves it across the significance level, outside the interval or
across zero? Simulation shows the two probabilities differ. At conventional power 0.8 roughly a third of significant
results are classed sensitive, because a p-value that lands near alpha is what a correctly sized trial produces much of
the time. At power 0.95 the share falls to about one in six.

`stress_design()` makes this a design quantity. It simulates the planned trial over a grid of sample sizes and effect
sizes, runs the light stress test on each simulated trial and reports the **robustness power**, the probability of a
significant and robust result, next to the conventional power.

```{r, eval = FALSE}
library(ballast)
des <- stress_design(n_per_arm = c(50, 75, 100, 150), delta = c(0, 4.5),
                     n_visits = 4, sigma = 10, rho = 0.6, dropout = 0.03,
                     covariance = "ar1h", method = "Satterthwaite", vcov = "Asymptotic",
                     n_trials = 200, cores = 8)
des
plot(des)
```

The print method names the smallest sample size per arm that reaches a target robustness power (0.8 by default) for
each non-zero effect. The plot draws both probabilities against the sample size, one panel per effect size, with the
null panel showing the type I error and the share of false positives that would be flagged.

## What the cells report

For every (sample size, effect) cell the table gives:

- `power` and `robustness_power`: significant, and significant and robust.
- `robust_given_sig`, `sensitive_given_sig`, `fragile_given_sig`: the verdict rates among significant results. Under the
  null these describe what a false positive looks like to the stress test.
- `marginal_given_sig`: how often the marginal flag would be set.
- `k1_given_sig`: how often removing one subject loses significance. With `fragility = TRUE` the greedy deletion search
  runs instead and `k_reached_given_sig` and `k_median` describe the fragility index.
- `tipping_margin` and `tipping_absorbed`, with `tipping = TRUE`: the shift applied to imputed active-arm values at
  which p crosses alpha, as a multiple of the effect, and the share of significant trials that absorb the whole grid.
- `max_shift_se`: the median, over trials, of the largest shift in pre-specified standard errors under the families.

## A small illustration

A fast pass without the deletion family, for the vignette build:

```{r, message = FALSE}
library(ballast)
des <- stress_design(n_per_arm = c(20, 40), delta = c(0, 6), n_visits = 3, n_trials = 3, loo = FALSE, seed = 2)
des
```

Three trials per cell is far too few for a real design; 200 per cell with the deletion family is a run of minutes to an
hour depending on the sample size, since the deletion family refits once per subject.

## Writing it into the analysis plan

The expected rates belong in the statistical analysis plan next to the pre-specified stress test. `stress_sap()` writes
the plan text; a sentence such as "under the design assumptions the probability of a significant and robust result is
0.72 and about one significant result in four is expected to be classed sensitive" gives the verdict after unblinding a
pre-registered comparison. A sensitive verdict then reads as the expected consequence of a p-value near alpha rather
than as a discovery, and a fragile verdict for a significant result, which the simulations put at well under one in a
hundred, reads as the warning it is.

## Assumptions in the simulator

`simulate_trial()` draws AR(1) errors with a common residual SD, a treatment effect growing linearly to `delta` at the
last visit, a baseline covariate, and dropout after each visit that depends on the current value. Heavy tails,
heteroscedastic visits, dropout depending on the unobserved next value and effect modification by baseline are
available as settings. The pre-specified covariance in the analysis need not be the true one; the covariance family
always includes the structures named in `alternatives`.
