| Title: | Truncation Time Selection for Average Hazard Analyses |
|---|---|
| Description: | Implements a two-stage, design-informed framework for selecting the truncation time in time-to-event trials analyzed with the average hazard estimand, motivated by pediatric oncology settings with small samples, slow accrual, and limited follow-up. Stage 1 validates a clinically proposed truncation time against the planned design using simulation-based diagnostics for risk-set support, follow-up coverage, estimability, and estimator stability, classifying it as Pass, Borderline, or Fail. Stage 2 performs constrained optimization over a grid of candidate truncation times within a clinical-distance window, maximizing a utility subject to feasibility constraints, with an independent evaluation run to assess the selected time. Supports proportional-hazards, early-, and delayed-effect patterns, uniform accrual with administrative censoring, and calibrated exponential random censoring. |
| Authors: | Xinyue Zhao [aut, cre], Haitao Pan [aut] |
| Maintainer: | Xinyue Zhao <[email protected]> |
| License: | GPL-3 |
| Version: | 0.1.0 |
| Built: | 2026-10-11 10:09:51 UTC |
| Source: | https://github.com/cran/AHTauDesign |
Evaluates whether a single proposed truncation time is
statistically supported under the planned two-arm trial design, and
classifies it as "Pass", "Borderline", or "Fail".
assess_tau( N, A, F_followup, tau, effect_model, alloc_ratio = 1, censor_params = list(add_random = FALSE), n_sim = 100, n_boot = 100, min_boot_valid_frac = 0.8, alpha = 0.05, feasibility_thresholds = list(), fail_thresholds = list() ) ## S3 method for class 'assess_tau' print(x, ...)assess_tau( N, A, F_followup, tau, effect_model, alloc_ratio = 1, censor_params = list(add_random = FALSE), n_sim = 100, n_boot = 100, min_boot_valid_frac = 0.8, alpha = 0.05, feasibility_thresholds = list(), fail_thresholds = list() ) ## S3 method for class 'assess_tau' print(x, ...)
N |
Total planned sample size (both arms combined). |
A |
Numeric. Accrual duration, in the time unit of the design
(e.g., months). Enrollment times are uniform on |
F_followup |
Numeric. Additional follow-up duration after the end
of accrual, in the same time unit as |
tau |
Numeric scalar. The single proposed truncation time to
assess, on the original time scale. Supplying a vector is an error;
use |
effect_model |
A named list describing the treatment-effect
assumption. Must contain |
alloc_ratio |
Numeric. Allocation ratio of treatment to control
(default |
censor_params |
A named list controlling random censoring in
addition to administrative censoring. Default
|
n_sim |
Integer. Number of simulated trial datasets over which
the feasibility diagnostics are averaged (default |
n_boot |
Integer. Number of bootstrap resamples drawn within
each simulated trial to estimate the standard error of the log
average-hazard-ratio estimate (default |
min_boot_valid_frac |
Numeric in |
alpha |
Numeric in |
feasibility_thresholds |
A named list overriding any of the
default Pass thresholds; see |
fail_thresholds |
A named list overriding any of the default
hard-failure rules; see |
x |
An object of class |
... |
Further arguments; currently unused. |
Feasibility is judged by Monte Carlo simulation of the planned trial.
For each simulated dataset the function computes the risk-set sizes at
, the risk-set proportion — the
proportion of participants remaining under observation and
event-free at , not administrative follow-up coverage
alone — and whether the log average-hazard ratio is estimable.
Averaging over replicates gives the feasibility diagnostics, which are
compared against fixed decision rules:
Pass: expected total risk-set size 30,
expected risk-set size 10 in each arm, risk-set
proportion , and estimability
probability 0.90.
Fail: expected total risk-set size < 20, or an
arm-specific risk-set size < 5, or risk-set proportion
< 0.10,
or estimability probability < 0.80.
Borderline: neither all Pass conditions nor any Fail condition is met.
assess_tau() evaluates exactly one truncation time per call.
To screen a grid of candidate values and optimize among them, use
optimize_tau().
The simulation settings n_sim, n_boot,
min_boot_valid_frac, and alpha have
developer-validated defaults and do not need to be changed in
ordinary use. For reproducibility, call set.seed() once
before assess_tau(); the function does not modify the
random-number-generator state internally.
An object of class "assess_tau": a named list with
components
feasibilityCharacter. "Pass",
"Borderline", or "Fail".
Expected total risk-set size at tauRounded to 1 decimal place.
Expected control-arm risk-set size at tauRounded to 1 decimal place.
Expected treatment-arm risk-set size at tauRounded to 1 decimal place.
Risk-set proportion at tauRounded to 4 decimal places.
Estimability probabilityRounded to 4 decimal places.
summaryA data.frame with one row per feasibility metric (value, Pass threshold, Fail threshold) and the feasibility classification as the last row.
tauThe assessed truncation time.
call_paramsA named list recording the design inputs, for provenance.
Components whose names contain spaces are accessed with backticks,
e.g. result$`Risk-set proportion at tau`.
effect_model <- list(type = "ph", lambda0 = -log(0.5)/24, HR = 0.5) # Settings reduced so this example runs quickly. Use the defaults # (n_sim = 100, n_boot = 100) or larger for real design work. set.seed(2026) assessment <- assess_tau( N = 60, A = 24, F_followup = 6, tau = 24, effect_model = effect_model, n_sim = 10, n_boot = 10 ) assessment$feasibility assessmenteffect_model <- list(type = "ph", lambda0 = -log(0.5)/24, HR = 0.5) # Settings reduced so this example runs quickly. Use the defaults # (n_sim = 100, n_boot = 100) or larger for real design work. set.seed(2026) assessment <- assess_tau( N = 60, A = 24, F_followup = 6, tau = 24, effect_model = effect_model, n_sim = 10, n_boot = 10 ) assessment$feasibility assessment
Returns the built-in hard-failure rules. A candidate is classified as
"Fail" if any one of them is violated.
default_fail_thresholds()default_fail_thresholds()
A named list with total_risk, arm_risk,
riskset_prop, and estimability.
default_fail_thresholds()default_fail_thresholds()
Returns the built-in thresholds a candidate must meet to be
classified as "Pass".
default_feasibility_thresholds()default_feasibility_thresholds()
A named list with min_total_risk, min_arm_risk,
min_riskset_prop, and min_estimability.
default_feasibility_thresholds()default_feasibility_thresholds()
Identifies a statistically feasible and clinically acceptable
truncation time from a candidate grid. Each candidate is classified
as "Pass", "Borderline", or "Fail"; the
admissible set is the intersection of the Pass set with the clinical
window ; the utility
is maximized over the admissible set; and a
clinical-retention rule decides whether the clinically proposed value
is kept.
optimize_tau( N, A, F_followup, tau_clin, tau_grid, effect_model, delta = 12, epsilon = 0.05, alloc_ratio = 1, censor_params = list(add_random = FALSE), n_sim = 100, n_boot = 100, min_boot_valid_frac = 0.8, alpha = 0.05 ) ## S3 method for class 'optimize_tau' print(x, ...)optimize_tau( N, A, F_followup, tau_clin, tau_grid, effect_model, delta = 12, epsilon = 0.05, alloc_ratio = 1, censor_params = list(add_random = FALSE), n_sim = 100, n_boot = 100, min_boot_valid_frac = 0.8, alpha = 0.05 ) ## S3 method for class 'optimize_tau' print(x, ...)
N |
Total planned sample size (both arms combined). |
A |
Numeric. Accrual duration. Enrollment times are uniform on
|
F_followup |
Numeric. Additional follow-up duration after the end of accrual. |
tau_clin |
Numeric scalar. The clinically proposed truncation
time (the anchor value). Must be contained in |
tau_grid |
Numeric vector. The candidate truncation times to evaluate (the search space). |
effect_model |
A named list describing the treatment-effect
assumption; see |
delta |
Numeric. Half-width |
epsilon |
Numeric. Relative utility tolerance |
alloc_ratio |
Numeric. Allocation ratio of treatment to control
(default |
censor_params |
A named list controlling random censoring; see
|
n_sim |
Integer. Number of simulated trial datasets; every
candidate in |
n_boot |
Integer. Number of bootstrap resamples drawn within
each simulated trial to estimate the standard error of the log
average-hazard-ratio estimate (default |
min_boot_valid_frac |
Numeric in |
alpha |
Numeric in |
x |
An object of class |
... |
Further arguments; currently unused. |
The two truncation-time arguments play distinct roles:
tau_clin is the clinically proposed anchor value, and
tau_grid is the search space. tau_clin must be an
element of tau_grid.
The procedure: (1) evaluate all candidates on the same simulated
trials; (2) classify each candidate; (3) build the admissible set;
(4) select the preliminary utility-optimal candidate
; (5) retain if it is admissible
and its utility is within a relative tolerance epsilon of the
best admissible utility, otherwise select .
The simulation settings n_sim, n_boot,
min_boot_valid_frac, and alpha have
developer-validated defaults and do not need to be changed in
ordinary use. For reproducibility, call set.seed() once
before optimize_tau(); the function does not modify the
random-number-generator state internally.
An object of class "optimize_tau": a named list with
components
candidate_summaryFull tau-by-tau table of feasibility, utility, power, and diagnostics.
T_passFeasible (Pass) candidates.
T_clin_windowCandidates inside the clinical window.
T_admThe admissible set.
tau_tildePreliminary utility-optimal candidate.
tau_starFinal selection (NA if no
selection was possible).
tau_clin_retainedLogical. TRUE if
tau_clin was retained; FALSE only when
tau_clin was an admissible Pass candidate but was not
retained because another candidate had sufficiently higher
utility; NA when the clinical-retention rule was not
applicable (e.g., tau_clin was classified as Fail or
Borderline, or no selection was possible).
stage1_status_tau_clinFeasibility status of
tau_clin.
decision_typeMachine-readable decision code, one
of "retained", "utility_driven",
"constraint_driven", "no_admissible_candidate",
or "no_positive_direction_candidate".
decision_messageA short explanation.
U_max, U_tau_clin
Best admissible utility
and the utility at tau_clin.
call_paramsFull provenance of the call.
effect_model <- list(type = "ph", lambda0 = -log(0.5)/24, HR = 0.5) # Settings reduced so this example runs quickly. Use the defaults # (n_sim = 100, n_boot = 100) and a finer tau_grid for real design work. set.seed(2026) optimization <- optimize_tau( N = 60, A = 24, F_followup = 6, tau_clin = 24, tau_grid = seq(6, 36, by = 6), effect_model = effect_model, delta = 12, epsilon = 0.05, n_sim = 10, n_boot = 10 ) optimization$tau_star optimizationeffect_model <- list(type = "ph", lambda0 = -log(0.5)/24, HR = 0.5) # Settings reduced so this example runs quickly. Use the defaults # (n_sim = 100, n_boot = 100) and a finer tau_grid for real design work. set.seed(2026) optimization <- optimize_tau( N = 60, A = 24, F_followup = 6, tau_clin = 24, tau_grid = seq(6, 36, by = 6), effect_model = effect_model, delta = 12, epsilon = 0.05, n_sim = 10, n_boot = 10 ) optimization$tau_star optimization
The primary function for users who want a final truncation-time
recommendation. It runs the Stage 1 feasibility assessment of the
clinically proposed value , the
feasibility-constrained utility optimization of Stage 2, fixes the
selection , and then compares and
in an independent evaluation run.
twostage_tau( N, A, F_followup, tau_clin, tau_grid, effect_model, delta = 12, epsilon = 0.05, alloc_ratio = 1, censor_params = list(add_random = FALSE), n_sim = 100, n_boot = 100, min_boot_valid_frac = 0.8, alpha = 0.05 ) ## S3 method for class 'twostage_tau' print(x, ...) ## S3 method for class 'twostage_tau' summary(object, ...) ## S3 method for class 'twostage_tau' plot(x, ...)twostage_tau( N, A, F_followup, tau_clin, tau_grid, effect_model, delta = 12, epsilon = 0.05, alloc_ratio = 1, censor_params = list(add_random = FALSE), n_sim = 100, n_boot = 100, min_boot_valid_frac = 0.8, alpha = 0.05 ) ## S3 method for class 'twostage_tau' print(x, ...) ## S3 method for class 'twostage_tau' summary(object, ...) ## S3 method for class 'twostage_tau' plot(x, ...)
N |
Total planned sample size (both arms combined). |
A |
Numeric. Accrual duration. Enrollment times are uniform on
|
F_followup |
Numeric. Additional follow-up duration after the end of accrual. |
tau_clin |
Numeric scalar. The clinically proposed truncation
time (the anchor value). Must be contained in |
tau_grid |
Numeric vector. The candidate truncation times to evaluate (the search space). |
effect_model |
A named list describing the treatment-effect
assumption; see |
delta |
Numeric. Half-width |
epsilon |
Numeric. Relative utility tolerance |
alloc_ratio |
Numeric. Allocation ratio of treatment to control
(default |
censor_params |
A named list controlling random censoring; see
|
n_sim |
Integer. Number of simulated trial datasets; every
candidate in |
n_boot |
Integer. Number of bootstrap resamples drawn within
each simulated trial to estimate the standard error of the log
average-hazard-ratio estimate (default |
min_boot_valid_frac |
Numeric in |
alpha |
Numeric in |
x |
An object of class |
... |
Further arguments; currently unused. |
object |
An object of class |
The selection stage and the independent evaluation stage consume
successive draws from a single random-number stream, so a single
set.seed() call before twostage_tau() makes the entire
run reproducible, with the two stages independent by construction.
The function itself takes no seed arguments and does not modify the
random-number-generator state internally.
The simulation settings n_sim, n_boot,
min_boot_valid_frac, and alpha have
developer-validated defaults and do not need to be changed in
ordinary use; n_sim and n_boot apply to both the
selection run and the independent evaluation run.
Three S3 methods layer the presentation: print() shows a
short summary block (Stage 1 status, , and the decision
message); summary() adds the candidate-level and evaluation
tables; plot() draws the utility curve
over the candidate grid with the feasibility classification, the
clinical window, , and the selected
marked (requires the ggplot2 package).
An object of class "twostage_tau": a named list whose
first three components are the reporting tables
candidate_summaryCandidate-level selection table:
one row per candidate tau with rounded diagnostics, effect
summaries, feasibility, distance to tau_clin,
within-window, utility, admissible, and selected flags.
final_decision_summaryTwo-column
(quantity, result) table with the Stage 1 status, candidate
sets, retention decision, final tau_star, decision
type, and efficiency gains.
eval_summaryIndependent evaluation table
comparing tau_clin and tau_star on fresh
simulations (NULL when no selection was possible).
followed by the individual selection components
(T_pass, T_adm, tau_tilde, tau_star,
tau_clin_retained, stage1_status_tau_clin,
decision_type, decision_message,
abs_power_gain, rel_utility_improvement),
selection_result (the full, unrounded
optimize_tau object), and call_params.
effect_model <- list(type = "ph", lambda0 = -log(0.5)/24, HR = 0.5) # Settings reduced so this example runs quickly. Use the defaults # (n_sim = 100, n_boot = 100) and a finer tau_grid for real design work. set.seed(2026) result <- twostage_tau( N = 60, A = 24, F_followup = 6, tau_clin = 24, tau_grid = seq(6, 36, by = 6), effect_model = effect_model, delta = 12, epsilon = 0.05, n_sim = 10, n_boot = 10 ) result summary(result) plot(result)effect_model <- list(type = "ph", lambda0 = -log(0.5)/24, HR = 0.5) # Settings reduced so this example runs quickly. Use the defaults # (n_sim = 100, n_boot = 100) and a finer tau_grid for real design work. set.seed(2026) result <- twostage_tau( N = 60, A = 24, F_followup = 6, tau_clin = 24, tau_grid = seq(6, 36, by = 6), effect_model = effect_model, delta = 12, epsilon = 0.05, n_sim = 10, n_boot = 10 ) result summary(result) plot(result)