Skip to contents

Applies the same posterior predictive decision calculation used by survival_adapt() to subject-level data observed at one interim look. The function does not simulate a trial or modify data. Participants who could still be enrolled before the maximum sample size are represented according to N_total, the observed arm counts, and rand_ratio.

Usage

evaluate_interim(
  data,
  data_cut,
  look,
  N_total,
  end_of_study,
  cutpoints = NULL,
  prior_surv = c(0.1, 0.1),
  prior_bin = c(1, 1),
  bin_method = "mc",
  rand_ratio = c(control = 1, treatment = 1),
  single_arm = FALSE,
  alternative = "greater",
  h0 = 0,
  Fn = 0.05,
  Sn = 0.9,
  prob_ha = 0.95,
  N_impute = 500,
  N_mcmc = 1000,
  mc_conf_level = 0.95,
  empty_interval = c("prior", "propagate", "error"),
  method = "logrank",
  binary_imputation = c("event-time", "bernoulli"),
  seed = NULL,
  Qn = 1,
  rmst_tau = end_of_study,
  prior_surv_final = prior_surv
)

Arguments

data

A required data frame with one row per enrolled subject and columns id, treatment, enrollment, time, event, and status. Treatment is coded 1 for treatment and 0 for control; single-arm data use 1. enrollment is measured from first participant randomization, which must be zero, and time is follow-up from that subject's randomization. See Details for the permitted character values in status.

data_cut

A required single finite, non-negative numeric value giving the calendar time of the interim data cut, measured from the same origin and in the same units as enrollment, time, end_of_study, and cutpoints.

look

A required positive integer identifying the prespecified interim look.

N_total

A required positive integer giving the maximum total sample size.

end_of_study

A required single finite, positive numeric value giving the planned follow-up time for each subject.

cutpoints

NULL (the default), or a numeric vector of finite, positive, strictly increasing interior follow-up times defining the piecewise-exponential model used for interim posterior estimation, predictive imputation, and final analysis. The number of interval-specific prior columns must be one greater than the number of cutpoints. NULL specifies a constant-hazard analysis model.

prior_surv

A numeric vector, matrix, or named list specifying the Gamma prior for the piecewise-exponential hazards used to generate outcomes during interim prediction. A length-two vector supplies shape and rate and applies the same prior to every arm and interval. A 2 by length(cutpoints) + 1 matrix supplies interval-specific values shared by all arms, with shapes in row 1 and rates in row 2. For independent arm-specific priors, supply a list named control and treatment in a two-arm design, or treatment in a single-arm design. Each list element may be a length-two vector or an interval-specific matrix. Both arms must be supplied; no values are borrowed or filled from the other arm. Rates must use the same time unit as event times, exposure, and cutpoints. The default is c(0.1, 0.1).

prior_bin

A length-two numeric vector of finite, positive shape parameters c(a, b) for the Beta(a, b) event-probability prior used when method = "bayes-bin". The same prior is applied to both arms. The default is c(1, 1), a uniform prior.

bin_method

A single character string selecting how to calculate the posterior probability for method = "bayes-bin". It must be one of "mc" (Monte Carlo sampling), "normal" (normal approximation), or "quadrature" (numerical integration). The default is "mc". The normal approximation can be inaccurate with sparse events or non-events and posterior event probabilities near 0 or 1. It can change whether prob_ha is exceeded. Increasing N_mcmc does not improve this approximation; use "quadrature" or sufficiently precise "mc" instead.

rand_ratio

A length-two positive integer vector giving the control to treatment allocation ratio at the maximum sample size. The default is c(control = 1, treatment = 1). Name the values control and treatment; either order is accepted. A legacy unnamed vector is interpreted as c(control, treatment). The maximum sample size must divide exactly according to this ratio. Ignored for single-arm designs.

single_arm

A single logical value indicating whether the design has one treatment arm and no control arm. The default is FALSE.

alternative

A single character string specifying the alternative hypothesis. It must be one of "greater" (the default), "less", or "two.sided". One-sided alternatives ("greater" and "less") are supported for method = "bayes-surv" and method = "bayes-bin". All three options are supported for method = "logrank", method = "cox", method = "rmst", method = "riskdiff-wald", and method = "riskdiff-fm". For an adverse event, benefit is in the "greater" direction for RMST (longer event-free time) and the "less" direction for the other methods (lower hazard or event probability).

h0

A single finite numeric value specifying the null hypothesis or margin. The default is 0. For Bayesian analyses, h0 must lie in [0, 1] for a single-arm design and [-1, 1] for a two-arm design.

  • When method = "bayes-surv", h0 is the null value of \(p_\textrm{treatment} - p_\textrm{control}\). In a single-arm design, h0 is the external benchmark event probability, often referred to as a performance goal (PG) or objective performance criterion (OPC).

  • When method = "bayes-bin", h0 is the null value of \(p_\textrm{treatment} - p_\textrm{control}\) for a two-arm design, or the null event probability for a single-arm design.

  • When method = "cox", h0 is the null log hazard ratio for treatment versus control. Use h0 = 0 for the usual hazard ratio of 1 null, or h0 = log(margin) for a non-inferiority margin specified as a hazard ratio. A Cox non-inferiority test should usually use alternative = "less".

  • When method = "rmst", h0 is the null treatment-control RMST difference in time units and must lie in [-rmst_tau, rmst_tau]. For non-inferiority allowing a loss of m time units, use h0 = -m and alternative = "greater".

  • When method = "riskdiff-wald" or method = "riskdiff-fm", h0 is the null value of \(p_\textrm{treatment} - p_\textrm{control}\) and must lie in [-1, 1].

  • When method = "logrank", only h0 = 0 is supported; this denotes the usual equal-survival null. Nonzero values are rejected because the standard log-rank statistic does not implement a nonzero effect margin.

Fn

NULL, or a single numeric probability in [0, 1] giving the threshold for stopping for futility at this look. Futility is declared when predictive success at the maximum sample size is strictly less than Fn. Set Fn = 0 or NULL to disable the maximum-sample calculation. The default is 0.05.

Sn

A single numeric probability in [0, 1] giving the threshold for stopping for expected success at this look. Expected success is declared when predictive success among the currently enrolled participants is strictly greater than Sn. The default is 0.9.

prob_ha

A single numeric probability in [0, 1] defining success in each completed-data analysis. For Bayesian methods this is compared with the posterior probability of the alternative; for frequentist methods it is compared with 1 - P. The default is 0.95.

N_impute

A positive integer giving the number of predictive imputations used at each interim look and, when requested, for final multiple imputation. The default is 500. An imputed Cox, RMST, or risk-difference final analysis requires at least two.

N_mcmc

A positive integer giving the number of posterior draws used within each method = "bayes-surv" and by method = "bayes-bin" when bin_method = "mc". The default is 1000.

mc_conf_level

A single numeric probability strictly between 0.5 and 1, giving the confidence level for one-sided exact binomial bounds reported as diagnostics of finite Monte Carlo uncertainty. The bounds do not alter completed-data success classifications or interim decisions, which use strict point-estimate comparisons with prob_ha, Qn, Sn, and Fn. The default is 0.95.

empty_interval

A single character string specifying how to handle empty piecewise-exponential intervals when updating Gamma hazard models for predictive imputation and Bayesian survival analysis. An empty interval is an interval with no exposed subjects in a treatment arm at the analysis time. "prior" (the default) leaves the interval at zero exposure time and zero events, so its posterior is driven only by its assigned survival prior. "propagate" is a legacy heuristic that copies exposure time and event counts from the nearest non-empty interval in the same treatment arm and emits a warning. "error" stops when any empty interval is found.

method

A single character string specifying the completed-data and final analysis. Available choices are a log-rank (method = "logrank") test, Cox proportional hazards regression model Wald test (method = "cox"), a restricted mean survival time difference Wald test (method = "rmst"), a fully-Bayesian piecewise-exponential analysis (method = "bayes-surv"), a Bayesian beta-binomial analysis of complete binary outcomes (method = "bayes-bin"), a frequentist risk-difference Wald test (method = "riskdiff-wald"), or a Farrington-Manning score test (method = "riskdiff-fm") of complete binary outcomes. The deprecated method = "riskdiff" is accepted as an alias for "riskdiff-wald" with a warning. The default is "logrank". See Details.

binary_imputation

A single character string selecting the predictive imputation approach for method = "bayes-bin", method = "riskdiff-wald", or method = "riskdiff-fm". "event-time" (the default) draws a conditional piecewise-exponential event time and reduces it to event status at end_of_study. "bernoulli" draws the endpoint status directly from its conditional event probability. This argument is ignored for time-to-event analysis methods.

seed

NULL (the default), or a single non-negative integer used for the predictive Monte Carlo calculation. A supplied seed makes the result reproducible and leaves the existing random-number state unchanged. With seed = NULL, the call uses and advances the current random-number state.

Qn

A single numeric probability in [0, 1] giving the upper threshold for declaring immediate trial success at this look. Immediate success is declared when predictive success among the currently enrolled participants is strictly greater than Qn. Qn must be greater than or equal to Sn. The default, 1, disables immediate-success stopping.

rmst_tau

A single finite positive restriction time for method = "rmst", in the same units as end_of_study. Defaults to end_of_study and must not exceed it. Prespecify the same horizon for all looks, imputations, and simulations. It may precede analysis cutpoints and does not shorten the planned follow-up or imputation horizon. Ignored for other methods.

prior_surv_final

A numeric vector, matrix, or named list specifying the Gamma analysis prior for each hypothetical completed trial when method = "bayes-surv". It accepts the same shared, interval-specific, and arm-specific forms as prior_surv and defaults to prior_surv. It should match the prior for the actual final analysis. Other methods do not use it in this interim calculation.

Value

An object of class goldilocks_interim, containing:

  • decision: a one-row decision summary;

  • probabilities: current- and maximum-sample predictive probabilities;

  • monte_carlo: estimates, standard errors, and diagnostic bounds;

  • diagnostics: observed status counts, potential accruals, warnings, imputation diagnostics, and resolved Gamma prior and posterior parameters by arm and interval;

  • trace: a one-row decision trace compatible with plot_trial_trace() and summarise_trial_trace();

  • metadata: the evaluated design, resolved prior design, package version, time-origin, data-cut, and random-number policy. For method = "bayes-surv", both Gamma priors are retained in metadata$design and metadata$prior_design; posterior diagnostics describe the predictive model based on the observed interim data. For method = "bayes-bin", metadata$design retains the normalized imputation prior (prior_surv), completed-data analysis prior (prior_bin), and imputation horizon (end_of_study).

Details

The arm-specific maximum enrollment is N_total * rand_ratio / sum(rand_ratio). Potential future accrual in each arm is its maximum enrollment minus its observed enrollment. Randomization block information and concealed future assignment order are unnecessary: the maximum-sample predictive calculation requires only the number of potential future participants in each arm.

The data$status values distinguish observed follow-up: "event" for an observed endpoint event, "complete" for event-free completion of end_of_study, "pending" for a subject still under follow-up, and "censored" for permanent early censoring. Pending and censored outcomes are predictively imputed conditional on time.

With method = "bayes-surv", prior_surv generates predictive outcomes and prior_surv_final is the analysis prior used to test each hypothetical completed trial for success, at both the current and maximum sample sizes. Supply the same final prior as in the prespecified trial design. The default prior_surv_final = prior_surv uses one prior for both roles. Other methods do not use prior_surv_final in this interim calculation; Bayesian binary completed-data analyses use prior_bin.

Qn, Sn, and Fn are scalar thresholds for this look. Immediate success is declared when the estimated probability of completed-data success among the current participants is strictly greater than Qn. Otherwise, expected success stops accrual for planned follow-up when that probability is strictly greater than Sn. If neither success rule applies, futility is declared when the corresponding maximum-sample probability is strictly less than Fn. Set Fn = 0 or NULL to disable futility. Exact one-sided Monte Carlo bounds are returned as diagnostics and do not drive any decision.

The function requires treatment assignments to perform the arm-specific posterior and completed-data analyses. In a blinded trial, an independent unblinded statistician or service should join the treatment assignments, run this function, and return the aggregate decision without distributing the subject-level input.

Predictive and analysis priors

For method = "bayes-surv", prior_surv_final is used during interim calculations as well as at the actual final analysis. The two arguments specify different roles, not simply different calendar stages:

CalculationGamma prior used
At interim, generate outstanding outcomes for enrolled and future participantsprior_surv
At interim, test each hypothetical completed trial at the current or maximum sample sizeprior_surv_final
At final analysis, impute missing outcomes if imputed_final = TRUEprior_surv_final
Analyze the actual final trial dataprior_surv_final

Within one interim predictive replicate, first update prior_surv with the observed events and exposure, draw hazards, and generate outstanding outcomes. Then start a fresh analysis posterior using prior_surv_final and the completed dataset's events and exposure. Compare its posterior probability of the alternative with prob_ha. The proportion of replicates that pass is the predictive probability used by Qn, Sn, and Fn.

To incorporate external evidence in prediction while using a weak analysis prior, explicitly supply an informative prior_surv and the chosen weak prior_surv_final. Omitting prior_surv_final uses prior_surv for both roles; the package does not automatically weaken the analysis prior. The predictive prior can still affect the selected sample size and stopping decision, so calibrate the design using both prespecified priors.

This table describes Bayesian survival analysis. For method = "bayes-bin", completed-data success tests at interim and final use prior_bin; prior_surv_final governs only optional final imputation. Frequentist completed-data tests use no analysis prior. evaluate_interim() performs the two interim calculations; use the same prior arguments as in the simulated design.

Examples

interim_data <- data.frame(
  id = 1:6,
  treatment = c(0, 1, 0, 1, 0, 1),
  enrollment = c(0, 1, 2, 3, 4, 5),
  time = c(6, 5, 4, 3, 2, 1),
  event = c(1, 0, 0, 1, 0, 0),
  status = c("event", "pending", "pending", "event", "pending", "pending")
)

evaluate_interim(
  data = interim_data,
  data_cut = 6,
  look = 1,
  N_total = 10,
  end_of_study = 12,
  rand_ratio = c(control = 1, treatment = 1),
  alternative = "less",
  N_impute = 5,
  seed = 2026
)
#> Goldilocks interim evaluation
#> Look: 1 (N = 6)
#> Decision: stop_futility
#> Predictive success if accrual stops now: 0
#> Predictive success at maximum sample size: 0