Changelog
DTEAssurance 1.3.0
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. -
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.
DTEAssurance 1.2.0
Breaking changes
-
calc_dte_assurance_adaptive()no longer returns aFinal_Decisioncolumn. That column was recomputed independently from a Cox Wald statistic at a flat threshold, ignoringanalysis_model$methodand the design’s boundaries, and could disagree withDecision. Use the new logicalSuccesscolumn, which is derived only fromDecision. AConvergedcolumn (MCMC convergence at the BPP interim;NAfor other futility types) is also returned.
New features
- New
"MatchedZ"futility type: stop for futility atfutility_IFif the interim Z-statistic falls belowGSD_model$futility_boundary_Z. - New exported functions:
calibrate_matched_futility_boundary()andsingle_matched_futility_rep()(calibrate a MatchedZ boundary), andrun_calibration_grid(),summarize_grid_by_lambda()andselect_lambda_star()(calibrate a BPP futility threshold over a grid). -
update_priors()returns Gelman-Rubin diagnostics and posterior latent-state probabilities as attributes (rhat,converged,Z_probs). -
BPP_func()acceptsfuture_boundaries, evaluating each predictive draw against the design’s remaining efficacy boundaries rather than a single final test.
Bug fixes
-
survival_test():"MW"now returns Z with the same sign convention as"LRT"/"WLRT"(positive Z favours treatment);"WLRT"uses the signed statistic fromnph::logrank.test()directly. -
survival_test()no longer fails with “could not find function Surv” when the survival package is not attached. -
apply_GSD_to_trial()computes interim and final statistics withanalysis_model$methodviasurvival_test()instead of a hard-coded Cox Wald statistic, and passesupdate_priors_sims/n_BPP_simsthrough. -
calc_dte_assurance_adaptive()andmake_rpact_design_from_GSD_model()recognise the"MatchedZ"futility type.
DTEAssurance 1.1.1
- Added
update_priors()to update elicited prior distributions using interim data. - Added
BPP_func()for computing the Bayesian predictive probability (BPP) from posterior samples. - Added
calibrate_BPP_timing()to determine the optimal timing for BPP-based futility looks. - Added
calibrate_BPP_threshold()to calibrate the BPP threshold for futility decisions. - Renamed
calc_dte_assurance_interim()tocalc_dte_assurance_adaptive()for consistency in adaptive design terminology. - Renamed
assurance_interim_shiny_app()toassurance_adaptive_shiny_app(). - Expanded functionality and UI elements in
assurance_adaptive_shiny_app().
DTEAssurance 1.0.1
CRAN release: 2025-10-24
- Fixed a bug in
calc_dte_assurance()affecting certain parameter configurations.
DTEAssurance 1.0.0
CRAN release: 2025-10-14
- Initial CRAN release.
- Added support for delayed treatment effects using elicited prior distributions.
- Introduced
calc_dte_assurance()for fixed designs. - Introduced
calc_dte_assurance_interim()for group sequential designs. - Added interactive Shiny applications for both design types.
- Included vignettes and a pkgdown site for documentation.