Calculates operating characteristics for a Group Sequential Trial with a Delayed Treatment Effect
calc_dte_assurance_adaptive.RdSimulates assurance and operating characteristics for a group sequential trial under prior uncertainty about a delayed treatment effect. The function integrates beliefs about control survival, treatment delay, post-delay hazard ratio, recruitment, and group sequential design (GSD) parameters.
Usage
calc_dte_assurance_adaptive(
n_c,
n_t,
control_model,
effect_model,
recruitment_model,
GSD_model,
analysis_model = NULL,
update_priors_sims = NULL,
PP_sims = NULL,
n_sims = 1000
)Arguments
- n_c
Control group sample size
- n_t
Treatment group sample size
- control_model
A named list specifying the control arm survival distribution:
dist: Distribution type ("Exponential" or "Weibull")parameter_mode: Either "Fixed" or "Distribution"fixed_type: If "Fixed", specify as "Parameters" or "Landmark"lambda,gamma: Scale and shape parameterst1,t2: Landmark timessurv_t1,surv_t2: Survival probabilities at landmarkst1_Beta_a,t1_Beta_b,diff_Beta_a,diff_Beta_b: Beta prior parameters
- effect_model
A named list specifying beliefs about the treatment effect:
delay_SHELF,HR_SHELF: SHELF objects encoding beliefsdelay_dist,HR_dist: Distribution types ("hist" by default)P_S: Probability that survival curves separateP_DTE: Probability of delayed separation, conditional on separation
- recruitment_model
A named list specifying the recruitment process:
method: "power" or "PWC"period,power: Parameters for power modelrate,duration: Comma-separated strings for PWC model
- GSD_model
A named list specifying the group sequential design:
events: Total number of eventsalpha_spending: User-specified cumulative alpha spent by each efficacy look (one value per element ofalpha_IF; the design usesrpact'stypeOfDesign = "asUser"). Futility looks are added to the design with zero alpha spent, so they do not change the efficacy critical values.alpha_IF: Information Fraction(s) at which we look for efficacyfutility_type: One of"none","Beta"(pre-specified beta-spending, viarpact),"PP"(predictive probability futility, D3-style), or"MatchedZ"(a fixed, externally-calibrated Z-statistic cutoff, D4/D5-style; the rule is applied as binding, i.e. the simulated trial stops when Z falls below the cutoff; seecalibrate_matched_futility_boundaryfor how to obtainfutility_boundary_Z).futility_IF: Information Fraction at which we look for futility (required for"PP"and"MatchedZ").beta_spending: Cumulative beta spending vector ("Beta"only).kappa: PP value below which we stop for futility ("PP"only).futility_boundary_Z: Z-statistic value below which we stop for futility ("MatchedZ"only).
- analysis_model
A named list specifying the final analysis and decision rule:
method: e.g."LRT","WLRT", or"MW".alpha: one-sided type I error level.alternative_hypothesis: direction of the alternative (e.g."one.sided").rho,gamma,t_star,s_star: additional parameters for WLRT or MW (if applicable).
- update_priors_sims
Number of posterior samples per chain for each interim dataset, passed to
update_priors. Required whenGSD_model$futility_type == "PP"; ignored otherwise.- PP_sims
Number of predictive simulations per interim dataset, passed to
PP_func. Required whenGSD_model$futility_type == "PP"; ignored otherwise.- n_sims
Number of simulations to run (default = 1000)
Value
A data frame with one row per simulated trial and the following columns:
- Trial
Simulation index
- Decision
Final interim/final decision outcome – one of
"Stop for efficacy","Stop for futility","Successful at final", or"Unsuccessful at final". This is the single source of truth for trial outcome; use it directly rather than deriving success/failure independently.- StopTime
Time at which the trial stopped or completed
- SampleSize
Total sample size at the time of decision
- Success
Logical recode of
Decisionfor convenience:TRUEifDecision %in% c("Stop for efficacy", "Successful at final"),FALSEotherwise.- Converged
For
"PP"designs, whether the interim MCMC fit converged (seeupdate_priors);NAfor other futility types, which involve no MCMC step.- PP_val
For
"PP"designs, the predictive probability at the futility look;NAotherwise (or if the trial stopped for efficacy before the futility look).- P_Z1, P_Z2, P_Z3
For
"PP"designs, the posterior probabilities of the three latent states at the futility look;NAotherwise.
Class: data.frame, with attribute settings: a list of
all arguments, plus the package, R, rjags and JAGS versions, the git
commit of the working directory, the hostname and a timestamp.
Examples
set.seed(123)
control_model <- list(dist = "Exponential", parameter_mode = "Fixed",
fixed_type = "Parameters", lambda = 0.1)
effect_model <- list(P_S = 1, P_DTE = 0,
HR_SHELF = SHELF::fitdist(c(0.6, 0.65, 0.7), probs = c(0.25, 0.5, 0.75), lower = 0, upper = 2),
HR_dist = "gamma",
delay_SHELF = SHELF::fitdist(c(3, 4, 5), probs = c(0.25, 0.5, 0.75), lower = 0, upper = 10),
delay_dist = "gamma"
)
recruitment_model <- list(method = "power", period = 12, power = 1)
GSD_model <- list(events = 300, alpha_spending = c(0.0125, 0.025),
alpha_IF = c(0.75, 1), futility_type = "none")
result <- calc_dte_assurance_adaptive(n_c = 300, n_t = 300,
control_model = control_model,
effect_model = effect_model,
recruitment_model = recruitment_model,
GSD_model = GSD_model,
n_sims = 10)
str(result)
#> 'data.frame': 10 obs. of 10 variables:
#> $ Trial : int 1 2 3 4 5 6 7 8 9 10
#> $ Decision : chr "Stop for efficacy" "Successful at final" "Stop for efficacy" "Stop for efficacy" ...
#> $ StopTime : num 12.5 13.6 12 12.4 12 ...
#> $ SampleSize: int 600 600 600 600 600 600 600 600 600 600
#> $ Success : logi TRUE TRUE TRUE TRUE TRUE TRUE ...
#> $ Converged : logi NA NA NA NA NA NA ...
#> $ PP_val : logi NA NA NA NA NA NA ...
#> $ P_Z1 : num NA NA NA NA NA NA NA NA NA NA
#> $ P_Z2 : num NA NA NA NA NA NA NA NA NA NA
#> $ P_Z3 : num NA NA NA NA NA NA NA NA NA NA
#> - attr(*, "settings")=List of 17
#> ..$ n_c : num 300
#> ..$ n_t : num 300
#> ..$ control_model :List of 4
#> .. ..$ dist : chr "Exponential"
#> .. ..$ parameter_mode: chr "Fixed"
#> .. ..$ fixed_type : chr "Parameters"
#> .. ..$ lambda : num 0.1
#> ..$ effect_model :List of 6
#> .. ..$ P_S : num 1
#> .. ..$ P_DTE : num 0
#> .. ..$ HR_SHELF :List of 16
#> .. .. ..$ Normal :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ mean: num 0.65
#> .. .. .. ..$ sd : num 0.0741
#> .. .. ..$ Student.t :'data.frame': 1 obs. of 3 variables:
#> .. .. .. ..$ location: num 0.65
#> .. .. .. ..$ scale : num 0.0654
#> .. .. .. ..$ df : num 3
#> .. .. ..$ Skewnormal :'data.frame': 1 obs. of 3 variables:
#> .. .. .. ..$ location: num 0.65
#> .. .. .. ..$ scale : num 0.0741
#> .. .. .. ..$ slant : num 0
#> .. .. ..$ Gamma :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ shape: num 76.9
#> .. .. .. ..$ rate : num 118
#> .. .. ..$ Log.normal :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ mean.log.X: num -0.432
#> .. .. .. ..$ sd.log.X : num 0.114
#> .. .. ..$ Log.Student.t :'data.frame': 1 obs. of 3 variables:
#> .. .. .. ..$ location.log.X: num -0.432
#> .. .. .. ..$ scale.log.X : num 0.101
#> .. .. .. ..$ df.log.X : num 3
#> .. .. ..$ Beta :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ shape1: num 52
#> .. .. .. ..$ shape2: num 108
#> .. .. ..$ mirrorgamma :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ shape: num 332
#> .. .. .. ..$ rate : num 245
#> .. .. ..$ mirrorlognormal:'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ mean.log.X: num 0.3
#> .. .. .. ..$ sd.log.X : num 0.0549
#> .. .. ..$ mirrorlogt :'data.frame': 1 obs. of 3 variables:
#> .. .. .. ..$ location.log.X: num 0.3
#> .. .. .. ..$ scale.log.X : num 0.0484
#> .. .. .. ..$ df.log.X : num 3
#> .. .. ..$ ssq :'data.frame': 1 obs. of 10 variables:
#> .. .. .. ..$ normal : num 4.07e-31
#> .. .. .. ..$ t : num 5.77e-12
#> .. .. .. ..$ skewnormal : num 2.96e-31
#> .. .. .. ..$ gamma : num 2.67e-05
#> .. .. .. ..$ lognormal : num 6e-05
#> .. .. .. ..$ logt : num 5.8e-05
#> .. .. .. ..$ beta : num 7.2e-06
#> .. .. .. ..$ mirrorgamma : num 6.18e-06
#> .. .. .. ..$ mirrorlognormal: num 1.39e-05
#> .. .. .. ..$ mirrorlogt : num 1.34e-05
#> .. .. ..$ best.fitting :'data.frame': 1 obs. of 1 variable:
#> .. .. .. ..$ best.fit: chr "skewnormal"
#> .. .. ..$ vals : num [1, 1:3] 0.6 0.65 0.7
#> .. .. .. ..- attr(*, "dimnames")=List of 2
#> .. .. .. .. ..$ : NULL
#> .. .. .. .. ..$ : NULL
#> .. .. ..$ probs : num [1, 1:3] 0.25 0.5 0.75
#> .. .. .. ..- attr(*, "dimnames")=List of 2
#> .. .. .. .. ..$ : NULL
#> .. .. .. .. ..$ : NULL
#> .. .. ..$ limits :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ lower: num 0
#> .. .. .. ..$ upper: num 2
#> .. .. ..$ notes : NULL
#> .. .. ..- attr(*, "class")= chr "elicitation"
#> .. ..$ HR_dist : chr "gamma"
#> .. ..$ delay_SHELF:List of 16
#> .. .. ..$ Normal :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ mean: num 4
#> .. .. .. ..$ sd : num 1.48
#> .. .. ..$ Student.t :'data.frame': 1 obs. of 3 variables:
#> .. .. .. ..$ location: num 4
#> .. .. .. ..$ scale : num 1.31
#> .. .. .. ..$ df : num 3
#> .. .. ..$ Skewnormal :'data.frame': 1 obs. of 3 variables:
#> .. .. .. ..$ location: num 4
#> .. .. .. ..$ scale : num 1.48
#> .. .. .. ..$ slant : num 0
#> .. .. ..$ Gamma :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ shape: num 7.29
#> .. .. .. ..$ rate : num 1.76
#> .. .. ..$ Log.normal :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ mean.log.X: num 1.37
#> .. .. .. ..$ sd.log.X : num 0.381
#> .. .. ..$ Log.Student.t :'data.frame': 1 obs. of 3 variables:
#> .. .. .. ..$ location.log.X: num 1.37
#> .. .. .. ..$ scale.log.X : num 0.335
#> .. .. .. ..$ df.log.X : num 3
#> .. .. ..$ Beta :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ shape1: num 4.5
#> .. .. .. ..$ shape2: num 6.63
#> .. .. ..$ mirrorgamma :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ shape: num 16.4
#> .. .. .. ..$ rate : num 2.69
#> .. .. ..$ mirrorlognormal:'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ mean.log.X: num 1.78
#> .. .. .. ..$ sd.log.X : num 0.25
#> .. .. ..$ mirrorlogt :'data.frame': 1 obs. of 3 variables:
#> .. .. .. ..$ location.log.X: num 1.78
#> .. .. .. ..$ scale.log.X : num 0.22
#> .. .. .. ..$ df.log.X : num 3
#> .. .. ..$ ssq :'data.frame': 1 obs. of 10 variables:
#> .. .. .. ..$ normal : num 7.7e-34
#> .. .. .. ..$ t : num 6.35e-12
#> .. .. .. ..$ skewnormal : num 3.08e-33
#> .. .. .. ..$ gamma : num 0.00029
#> .. .. .. ..$ lognormal : num 0.000644
#> .. .. .. ..$ logt : num 0.000623
#> .. .. .. ..$ beta : num 3.4e-05
#> .. .. .. ..$ mirrorgamma : num 0.000127
#> .. .. .. ..$ mirrorlognormal: num 0.000283
#> .. .. .. ..$ mirrorlogt : num 0.000274
#> .. .. ..$ best.fitting :'data.frame': 1 obs. of 1 variable:
#> .. .. .. ..$ best.fit: chr "normal"
#> .. .. ..$ vals : num [1, 1:3] 3 4 5
#> .. .. .. ..- attr(*, "dimnames")=List of 2
#> .. .. .. .. ..$ : NULL
#> .. .. .. .. ..$ : NULL
#> .. .. ..$ probs : num [1, 1:3] 0.25 0.5 0.75
#> .. .. .. ..- attr(*, "dimnames")=List of 2
#> .. .. .. .. ..$ : NULL
#> .. .. .. .. ..$ : NULL
#> .. .. ..$ limits :'data.frame': 1 obs. of 2 variables:
#> .. .. .. ..$ lower: num 0
#> .. .. .. ..$ upper: num 10
#> .. .. ..$ notes : NULL
#> .. .. ..- attr(*, "class")= chr "elicitation"
#> .. ..$ delay_dist : chr "gamma"
#> ..$ recruitment_model :List of 3
#> .. ..$ method: chr "power"
#> .. ..$ period: num 12
#> .. ..$ power : num 1
#> ..$ GSD_model :List of 4
#> .. ..$ events : num 300
#> .. ..$ alpha_spending: num [1:2] 0.0125 0.025
#> .. ..$ alpha_IF : num [1:2] 0.75 1
#> .. ..$ futility_type : chr "none"
#> ..$ analysis_model :List of 3
#> .. ..$ method : chr "LRT"
#> .. ..$ alpha : num 0.025
#> .. ..$ alternative_hypothesis: chr "one.sided"
#> ..$ update_priors_sims: NULL
#> ..$ PP_sims : NULL
#> ..$ n_sims : num 10
#> ..$ package_version : chr "1.3.0"
#> ..$ r_version : chr "R version 4.6.1 (2026-06-24)"
#> ..$ rjags_version : chr "4.17"
#> ..$ jags_version :Classes 'package_version', 'numeric_version' hidden list of 1
#> .. ..$ : int [1:3] 4 3 2
#> ..$ git_commit : chr "b69f7c56de90bc460a4624eeaa011074178eee86"
#> ..$ hostname : chr "runnervmmprz5"
#> ..$ timestamp : chr "2026-10-13 16:04:00.682546"