DTEAssurance is an R package for implementing assurance methodology
in the design of clinical trials with an anticipated delayed treatment
effect (DTE).
It uses elicited prior distributions—via the
SHELF framework—for the
delay duration and post-delay hazard ratio, and simulates operating
characteristics to inform trial design.
The methodology is based on the following papers:
-
Salsbury JA, Oakley JE, Julious SA, Hampson LV.
Assurance methods for designing a clinical trial with a delayed treatment effect.
Statistics in Medicine, 2024; 43(19): 3595–3612. doi:10.1002/sim.10136 -
Salsbury JA, Oakley JE, Julious SA, Hampson LV.
Adaptive clinical trial design with delayed treatment effects using elicited prior distributions.
arXiv preprint, 2025; arXiv:2509.07602 [under revision at Pharmaceutical Statistics]
You can install DTEAssurance on CRAN using:
install.packages("DTEAssurance")library(DTEAssurance)Launch the interactive app to explore assurance under delayed treatment effects:
DTEAssurance::assurance_shiny_app()You can also use the package offline via the main function:
DTEAssurance::calc_dte_assurance()This function requires the following arguments:
n_c: Number of patients in the control groupn_t: Number of patients in the treatment groupcontrol_model: A named list specifying the control arm survival distributioneffect_model: A named list specifying beliefs about the treatment effectcensoring_model: A named list specifying the censoring mechanismrecruitment_model: A named list specifying the recruitment processanalysis_model: A named list specifying the statistical test and decision rulen_sims: Number of simulations to run
An example of this is shown:
control_model <- list(dist = "Exponential", parameter_mode = "Fixed", fixed_type = "Parameters", lambda = 0.1)
effect_model <- list(delay_SHELF = SHELF::fitdist(c(3, 4, 5), probs = c(0.25, 0.5, 0.75), lower = 0, upper = 10),
delay_dist = "gamma",
HR_SHELF = SHELF::fitdist(c(0.55, 0.6, 0.7), probs = c(0.25, 0.5, 0.75), lower = 0, upper = 1.5),
HR_dist = "gamma",
P_S = 1, P_DTE = 0)
censoring_model <- list(method = "Time", time = 12)
recruitment_model <- list(method = "power", period = 12, power = 1)
analysis_model <- list(method = "LRT", alpha = 0.025, alternative_hypothesis = "one.sided")
result <- calc_dte_assurance(n_c = 300, n_t = 300,
control_model = control_model,
effect_model = effect_model,
censoring_model = censoring_model,
recruitment_model = recruitment_model,
analysis_model = analysis_model,
n_sims = 100)
str(result)
#> List of 4
#> $ assurance : num 0.83
#> $ CI : num [1, 1:2] 0.742 0.898
#> $ duration : num 12
#> $ sample_size: num 600We can vary the sample sizes and plot the resulting output:
result <- calc_dte_assurance(n_c = seq(50, 500, by = 50),
n_t = seq(50, 500, by = 50),
control_model = control_model,
effect_model = effect_model,
censoring_model = censoring_model,
recruitment_model = recruitment_model,
analysis_model = analysis_model,
n_sims = 500)Launch the interactive shiny app to explore assurance under delayed
treatment effects using group sequential designs:
DTEAssurance::assurance_GSD_shiny_app()You can also use the package offline via the main function:
DTEAssurance::calc_dte_assurance_adaptive()This function requires the following arguments:
n_c: Number of patients in the control groupn_t: Number of patients in the treatment groupcontrol_model: A named list specifying the control arm survival distributioneffect_model: A named list specifying beliefs about the treatment effectrecruitment_model: A named list specifying the recruitment processGSD_model: A named list specifying the group sequential designn_sims: Number of simulations to run
An example of this is shown:
control_model <- list(dist = "Exponential", parameter_mode = "Fixed", fixed_type = "Parameters", lambda = 0.08)
effect_model <- list(delay_SHELF = SHELF::fitdist(c(3, 4, 5), probs = c(0.25, 0.5, 0.75), lower = 0, upper = 10),
delay_dist = "gamma",
HR_SHELF = SHELF::fitdist(c(0.55, 0.6, 0.7), probs = c(0.25, 0.5, 0.75), lower = 0, upper = 1.5),
HR_dist = "gamma",
P_S = 0.9, P_DTE = 0.7)
recruitment_model <- list(method = "power", period = 12, power = 1)
GSD_model <- list(events = 450,
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 = 500)
str(result)
#> 'data.frame': 500 obs. of 5 variables:
#> $ Trial : int 1 2 3 4 5 6 7 8 9 10 ...
#> $ Decision : chr "Stop for efficacy" "Stop for efficacy" "Successful at final" "Stop for efficacy" ...
#> $ StopTime : num 21.6 20.4 26.8 17.9 18.7 ...
#> $ SampleSize : int 600 600 600 600 600 600 600 600 600 600 ...
#> $ Final_Decision: chr "Successful" "Successful" "Successful" "Successful" ...design_summary <- result %>%
summarise(
Assurance = mean(Decision %in% c("Stop for efficacy", "Successful at final")),
`Pr(Early Fut.)` = mean(Decision %in% c("Stop for futility")),
`Pr(Early Eff.)` = mean(Decision %in% c("Stop for efficacy")),
`Average Duration` = round(mean(StopTime, na.rm = TRUE), 2),
`Average Sample Size` = round(mean(SampleSize, na.rm = TRUE), 2)
)
design_summary
#> Assurance Pr(Early Fut.) Pr(Early Eff.) Average Duration Average Sample Size
#> 1 0.7 0 0.528 22.38 600