---
title: "Applying predictive decisions to an observed interim data cut"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Applying predictive decisions to an observed interim data cut}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
```

```{r setup, message = FALSE}
library(goldilocks)
```

`survival_adapt()` simulates a complete adaptive trial. `evaluate_interim()`
instead applies the same predictive decision calculation to one observed
interim data cut. It does not generate event, censoring, or enrollment times,
and it does not retain a participant-level copy of the input in its result.

## Preparing the data cut

The input has one row for every enrolled participant and uses a common time
unit throughout. Calendar-time `enrollment` is measured from first participant
randomization at time zero. Subject-level `time` is measured from that
participant's randomization.

The status values make the reason for incomplete follow-up explicit:

| `status` | Interpretation |
|---|---|
| `event` | The endpoint event has been observed. |
| `complete` | Event-free follow-up reached `end_of_study`. |
| `pending` | The participant remains under follow-up. |
| `censored` | Follow-up ended early without an event. |

A blinded data-management team can prepare enrollment, follow-up, event, and
status fields without access to treatment assignments:

```{r blinded-data}
blinded_cut <- data.frame(
  id = 1:8,
  enrollment = 0:7,
  time = c(8, 7, 6, 5, 4, 3, 2, 1),
  event = c(1, 0, 0, 1, 0, 0, 0, 0),
  status = c(
    "event", "pending", "censored", "event",
    "pending", "pending", "pending", "pending"
  )
)

blinded_cut
```

The calculation itself is arm-specific. An independent unblinded statistician
or service therefore joins the treatment assignment before running it. The
participant-level input need not be distributed with the aggregate result.

```{r unblinded-data}
randomization_export <- data.frame(
  id = 1:8,
  treatment = c(0, 1, 0, 1, 0, 1, 0, 1)
)

interim_cut <- blinded_cut
interim_cut$treatment <- randomization_export$treatment[
  match(interim_cut$id, randomization_export$id)
]
interim_cut <- interim_cut[
  c("id", "treatment", "enrollment", "time", "event", "status")
]
```

## Evaluating the look

Suppose this is the second planned look of a trial with maximum sample size 12,
equal randomization, and ten time units of follow-up per participant:

```{r evaluate-look}
interim_result <- evaluate_interim(
  data = interim_cut,
  data_cut = 8,
  look = 2,
  N_total = 12,
  end_of_study = 10,
  rand_ratio = c(control = 1, treatment = 1),
  method = "logrank",
  alternative = "less",
  Fn = 0.05,
  Sn = 0.90,
  Qn = 1,
  prob_ha = 0.95,
  N_impute = 20,
  seed = 20260831
)

interim_result
interim_result$decision
interim_result$monte_carlo
```

Here `Qn = 1` disables an immediate success claim. Crossing `Sn` stops accrual
for expected success while enrolled participants continue follow-up. The method,
alternative, and thresholds must match the prespecified trial design.

At the maximum sample size, equal randomization implies six participants per
arm. Four have already accrued in each arm, so the predictive calculation
includes two potential future participants per arm:

```{r allocation-diagnostics}
interim_result$diagnostics$target_allocation
interim_result$diagnostics$current_allocation
interim_result$diagnostics$potential_accruals
```

No block size or future randomization sequence is needed. The design must have
an exactly allocable maximum sample size: for example, a 1:2 ratio requires
`N_total` to be divisible by three. Observed enrollment in either arm cannot
already exceed its implied maximum.

## Using separate predictive and analysis priors

Suppose a sponsor wants external evidence to inform the prediction of future
events, while the Bayesian survival success test uses a diffuse prior. Supply
both `prior_surv` and `prior_surv_final`. **The latter is used now, inside each
interim predictive replicate, as well as at the actual final analysis.**

| Step in one interim predictive replicate | Prior used |
|---|---|
| Update observed events and exposure, draw hazards, and generate outstanding outcomes | `prior_surv` |
| Analyze that hypothetical completed trial and compare its posterior probability with `prob_ha` | `prior_surv_final` |

Repeat these steps and calculate the fraction of completed trials that pass.
The same pair of priors is used for current-sample and maximum-sample
predictions. Each completed-data analysis starts from the specified analysis
prior, rather than using the prediction posterior as a new prior.

For this illustration, interpret the data's time units as months. The
predictive Gamma priors below have mean hazards of 0.05 and 0.03 per month for
control and treatment. Their rate parameters use patient-months. These values
are illustrative; the actual predictive prior needs justification from the
external evidence and a prior-predictive assessment.

```{r separate-prior-look}
predictive_prior <- list(
  control = c(shape = 10, rate = 200),
  treatment = c(shape = 6, rate = 200)
)
analysis_prior <- c(shape = 0.1, rate = 0.1)

bayes_prior_result <- evaluate_interim(
  data = interim_cut,
  data_cut = 8,
  look = 2,
  N_total = 12,
  end_of_study = 10,
  method = "bayes-surv",
  alternative = "less",
  h0 = 0,
  prior_surv = predictive_prior,    # Generates outstanding outcomes
  prior_surv_final = analysis_prior, # Tests each hypothetical completed trial
  Fn = 0.05,
  Sn = 0.90,
  Qn = 1,
  prob_ha = 0.975,
  N_impute = 100,
  N_mcmc = 1000,
  seed = 20260909
)

knitr::kable(
  bayes_prior_result$diagnostics$prior[
    c("stage", "arm", "shape", "rate", "mean_hazard")
  ],
  digits = 3,
  caption = "Gamma priors used in the two parts of this interim calculation."
)
bayes_prior_result$probabilities
```

Here the rows labelled `final` describe the analysis prior already used to
test the hypothetical completed datasets. `diagnostics$posterior` describes
the predictive posterior based on the observed interim data.

**Omitting `prior_surv_final` would also use `predictive_prior` in the success
tests. The package does not automatically replace an informative predictive
prior with a weak analysis prior.** The two priors need not be distinct; the
default intentionally uses one prior for both roles.

Use these same two arguments in `survival_adapt()` or `sim_trials()` when
calibrating the design. The small Monte Carlo sizes here demonstrate the API;
precision and operating characteristics must be assessed for the deployed
design. At the actual final analysis, `prior_surv_final` is also used for any
optional imputation of missing outcomes. Even with a separate analysis prior,
predictive borrowing can affect the stopping decision and sample size.

This example concerns `method = "bayes-surv"`. With `method = "bayes-bin"`,
the completed-data success tests use `prior_bin` at both interim and final;
`prior_surv_final` controls only optional final imputation.

## Using a prespecified RMST endpoint

For a design that prespecifies RMST as its analysis, supply `method = "rmst"`
and the fixed restriction time. The same illustrative data cut can demonstrate
this separate design, targeting treatment-minus-control RMST through six time
units while follow-up continues through ten:

```{r evaluate-rmst-look}
rmst_result <- evaluate_interim(
  data = interim_cut,
  data_cut = 8,
  look = 2,
  N_total = 12,
  end_of_study = 10,
  rand_ratio = c(control = 1, treatment = 1),
  method = "rmst",
  rmst_tau = 6,
  alternative = "greater",
  h0 = 0,
  Fn = 0.05,
  Sn = 0.90,
  Qn = 1,
  prob_ha = 0.95,
  N_impute = 20,
  seed = 20260908
)

rmst_result$decision
rmst_result$monte_carlo
rmst_result$metadata$design[c("method", "rmst_tau", "alternative", "h0")]
```

Positive effects mean longer event-free time on treatment, so benefit uses
`alternative = "greater"`. Both `h0` and `rmst_tau` use the data's time units.
The horizon remains fixed across looks and predictive imputations. Input
`status = "complete"` still requires event-free follow-up to `end_of_study`,
even when a participant has already reached `rmst_tau`. The
[RMST vignette](rmst.html) explains the final analysis and its support and
variance requirements. These small Monte Carlo examples demonstrate the API;
the deployed design needs its own calibration and precision assessment.

## Reviewing and retaining the audit trail

The decision uses the Monte Carlo point estimates. The standard errors and
exact one-sided bounds describe finite-draw uncertainty but do not change the
decision. The interim record contains the same quantities retained for a
simulated adaptive trial and can be summarized or plotted in the same way:

```{r audit-trace}
summarise_trial_trace(interim_result)
interim_result$trace
```

The saved audit information records the evaluated design, package version,
data cut, time-origin convention, and simulation seed. Supplying `seed` makes
the predictive calculation exactly reproducible.
