Assurance Methods for Clinical Trials with a Delayed Treatment Effect
Overview
Provides functions for planning clinical trials subject to a delayed treatment effect using assurance-based methods. Includes two 'shiny' applications for interactive exploration, simulation, and visualisation of trial designs and outcomes. The methodology is described in: Salsbury JA, Oakley JE, Julious SA, Hampson LV (2024) "Assurance methods for designing a clinical trial with a delayed treatment effect" doi:10.1002/sim.10136, Salsbury JA, Oakley JE, Julious SA, Hampson LV (2024) "Adaptive clinical trial design with delayed treatment effects using elicited prior distributions" doi:10.48550/arXiv.2509.07602.
Results from 1.2.0 are not reproduced exactly: the event-cut convention
(below) and the exponential predictive simulation changed.
Changes in behaviour
- One event-cut convention everywhere.
cens_data(cens_method = "Events", cens_events = k)is now the only routine that cuts a trial at an analysis (used byapply_GSD_to_trial(),single_grid_rep()and the new paired runner). Cutting atkevents leaves exactlykevents: previously the group-sequential code censored thek-th event. Event counts at an information fraction arefloor(IF * total_events)(with a small tolerance), replacingceiling(); information fractions are rounded to 6 dp wherever they are compared. PP_func(): an exponential control arm now runs the Weibull code path withgamma_c = 1. This fixes the exponential branch for treated patients censored before the delay, where one uniform draw both chose the branch and placed the event time, so the late-branch time could fall below the delay. Weibull results are unchanged.
Show all changes in 1.3.0Hide the rest of the changes in 1.3.0
make_rpact_design_from_GSD_model(): for"PP"and"MatchedZ"futility, the efficacy critical values are taken from the efficacy-only design. A zero-alpha futility look cannot change them, but rpact's numerical integration moved them by about 8e-5 when the futility look was close to an efficacy look (e.g. 0.7 and 0.75).update_priors():convergedis now computed over finite R-hat values only and isNA(notTRUE) when none are finite.summarize_grid_by_kappa()andselect_kappa_star()are replaced.power_LCBis now a one-sided 95% exact (Clopper-Pearson) lower bound (argumentlcb_level, replacingconf_level); new columnsn,n_NA_dropped,power_SE,ESS_SE; replicates withNAPP_valare dropped with a warning;exclude_nonconvergedoption.select_kappa_star()accepts per-scenario floors, treats anNAlower bound as infeasible, breaks ties in null ESS towards the larger kappa, and reports power and floors in the feasibility table.
New features
single_paired_rep()andrun_paired_scenario(): one simulated trial per replicate with one PP evaluation, recording interim, efficacy-look and final statistics (log-rank and modestly weighted log-rank) so that every design (D1-D5) and kappa is a post hoc summary.run_paired_scenario()runs in parallel chunks with an RDS checkpoint and resumes from it.compute_relative_floors(): D2 power minus a margin, per alternative scenario, for use aspower_floor.update_priors(jags_seed = )makes the MCMC reproducible, and new attributesrhat_max,n_nonfinite_rhatandn_retained_total.survival_test(return_HR = ):FALSEskips the Cox fit (used by the PP and group-sequential code, where the hazard ratio is not needed).calc_dte_assurance_adaptive()returnsPP_val,P_Z1,P_Z2,P_Z3per trial and asettingsattribute (arguments, package and R versions, git commit if available, timestamp).- Internal
simulate_trial_with_recruitment(force_state = )fixes the latent state, and the simulated data carry atruthattribute. inst/benchmark/time_one_rep.R(in the source repository only) times one paired replicate at the manuscript settings.make_gsd_design()(exported; previously the internalmake_rpact_design_from_GSD_model(), kept as an alias for one release) andapply_GSD_to_trial()are now exported and documented.apply_design_rule(): D1-D5 decisions post hoc fromrun_paired_scenario()output, using the same decision labels asapply_GSD_to_trial(). A test checks that both give identical decisions, stop times and sample sizes on the same simulated trials.run_paired_scenario()is the single entry point for the paper's simulation tables.settingsreturned by the simulation functions now record all arguments plus the package, R, rjags and JAGS versions, the git commit of the working directory, the hostname and a timestamp.
Internal tidy-up (no change in results unless stated)
- One test wrapper (
run_test()) and one truth simulator (simulate_trial_from_truth()) replace repeated code; outputs are identical under a fixed seed. - Weibull control parameters from two landmark survival probabilities are computed in closed form (as in the
update_priors()prior) instead of withnleqslv, which could fail silently. Results agree to about 1e-8 relative; invalid landmarks (S(t2) <= 0 or S(t2) >= S(t1)) now give an informative error.nleqslvmoves from Imports to Suggests. The assurance Shiny app uses the same closed form. survival_test():alphahas no default (it previously defaulted to 0.05;alpha = NULLreturnsSignif = NAwhen onlyZis needed), the documented defaultalternativeis now the actual default ("one.sided"), andSignifis always logical (FALSEifZisNA).
History of earlier fixes (now removed from the code comments)
- The PP calculation evaluates the full group-sequential success event (crossing any remaining efficacy boundary, or success at the final analysis), not a single final test at a flat alpha.
- The trial evaluation in
apply_GSD_to_trial()andcalc_dte_assurance_adaptive()uses the specified test statistic (analysis_model$method) and the design's boundaries, replacing a hard-coded Cox Wald statistic at a flatqnorm(0.975);Successis derived only fromDecision. "MatchedZ"futility looks are included in the design's information-rate grid with zero alpha spent.update_priors()monitors the latent stateZand returns R-hat and state-probability diagnostics; calibration output records them.- The MW statistic from
nphRCT::wlrt()is negated so that positiveZmeans benefit for all three methods. calibrate_PP_timing()defaults forupdate_priors_simsandPP_simsare 1000 and 2000 (previously hard-coded to 100 and 50).
Deprecated (kept, to be removed in a future release)
- The exponential control arm in
PP_func()andupdate_priors(), the legacycensoring_modelfallback ofPP_func(),calibrate_PP_threshold()(and its internalsingle_calibration_rep()), and the internalsummarize_gsd_results()andsummarize_convergence().
Stricter inputs
PP_func():n_simsis required.calc_dte_assurance_adaptive():update_priors_simsandPP_simsare required whenfutility_type = "PP".- The PP code paths stop unless recruitment is uniform (
recruitment_model$method = "power",power = 1), the assumption under whichPP_func()draws future recruitment times.
Documentation
update_priors():n_samplesis per chain (totaln.chains * n_samples)."MatchedZ"futility is applied as binding (the trial stops).GSD_model$alpha_spendingis user-specified cumulative alpha (typeOfDesign = "asUser").
Renamed to match the manuscript notation (no behaviour change)
- The predictive probability is now called PP and its futility threshold kappa, as in the manuscript:
BPP_func()->PP_func(); its return elementBPP_df->PP_df.calibrate_BPP_threshold()->calibrate_PP_threshold()(returnsPP_vec) andcalibrate_BPP_timing()->calibrate_PP_timing()(returnsPP_values).summarize_grid_by_lambda()->summarize_grid_by_kappa()(argumentkappa_grid, columnkappa) andselect_lambda_star()->select_kappa_star()(returnskappa_star).GSD_model$futility_type = "BPP"->"PP"andGSD_model$BPP_threshold->GSD_model$kappa.n_BPP_sims->PP_simsincalc_dte_assurance_adaptive(), so the argument has the same name everywhere.- The
BPP_valcolumn of the calibration output is nowPP_val. - Internally, the treatment-arm post-delay rate is now named
lambda_e(inPP_func()and in theupdate_priors()JAGS models); the models are otherwise unchanged. - A "Notation" section in the README maps manuscript symbols to package identifiers.
Deprecated (to be removed in the next release)
BPP_func(),calibrate_BPP_threshold(),calibrate_BPP_timing(),summarize_grid_by_lambda()andselect_lambda_star()still work but warn and forward to their replacements. Returned element and column names are not translated back to the old names.futility_type = "BPP"andGSD_model$BPP_thresholdare accepted bycalc_dte_assurance_adaptive()with a warning and mapped to"PP"andGSD_model$kappa.
From NEWS.md in the release
Install
Health
- OK13 OK2026-08-05
- NOTE12 OK, 1 NOTE2026-08-01
- OK13 OK2026-06-09
- ERROR12 OK, 1 ERROR2026-06-08
- OK14 OK2026-03-10
Documentation
- Help pages
- 30 (4 internal)
- Examples that run
- 100%14 run in a plain check (2 of them under a condition)
- Exported functions with examples
- 56%
- Documented parameters
- 89%
- Return-value docs
- 100%
- Help pages citing references
- 0%
Downloads
Repository
- PRs merged (all time)
- 100%
- Median days to close, 50 most recently updated closed issues
- not measured
- Median days to close, 50 most recently updated closed PRs
- 0
Forks over time
Issues over time
Commits over time
Commit identities over time
9 development-tooling and community-health practices detected across 5 families in the upstream repository
Checks run against github.com/jamesalsbury/dteassurance on 2026-10-21.
GitHub Pages site last deployed 2026-10-13 · The repository has a site deploy workflow
pkgdown site last built 2026-10-13
Show all practicesHide 1 practice
This repository shows signs of AI coding tools.
- Claude Codefirst seen 2026-09-27Pull request it wrote: opened by a project memberCommits: 7 by its own account · at least 7 crediting it in the message
- Claude Opus 5.57 commits · Sep to Oct 2026
Dependencies
Code & Tests
Datasets
People & History
Pick two releases to compare their code metrics.
- 1.3.0Latest2026-10-13 · current release · diff ↗ ·
added 17 exports
PP_func, apply_GSD_to_trial, apply_design_rule, calibrate_PP_threshold, calibrate_PP_timing, calibrate_matched_futility_boundary, compute_relative_floors, make_gsd_design, make_rpact_design_from_GSD_model, run_calibration_grid, run_paired_scenario, select_kappa_star, select_lambda_star, single_matched_futility_rep, single_paired_rep, summarize_grid_by_kappa, summarize_grid_by_lambda - RR 4.6.0 released · 2026-04-24
- 1.1.02025-12-02 · diff ↗ ·
removed 2 exports
assurance_GSD_shiny_app, calc_dte_assurance_interimadded 6 exports
BPP_func, assurance_adaptive_shiny_app, calc_dte_assurance_adaptive, calibrate_BPP_threshold, calibrate_BPP_timing, update_priors - 1.0.12025-10-24 · diff ↗
- 1.0.02025-10-14
- RR 4.5.0 released · 2025-04-11
Package metadata
- First published
- 2025-10-14
- Total releases
- 4 / 1 yrs
- License
- MIT + file LICENSE OSI
- Minimum R
- ≥ 4.0
- Bundled data
- 732 KB / 4 files
- Download size
- 1.1 MB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("DTEAssurance")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-24, which the citation names so these numbers can be found later. More on citing and the projects behind them.