R/lrsim_bmTrtSel.R
lrsim_bmTrtSel.RdSimulates a two-stage seamless phase II/III trial in which several doses are compared with a common control. At the end of phase II a single dose is carried forward based on the posterior benefit-risk tradeoff of a binary short-term biomarker endpoint and a binary toxicity endpoint. The confirmatory phase III analysis is performed on a time-to-event long-term endpoint linked to the biomarker through the copula correlation, and the type I error rate is protected by a closed testing procedure combined across the two stages.
lrsim_bmTrtSel(
phase2SampleSizePerArm = NA_integer_,
phase3SampleSizePerArmMin = NA_integer_,
phase3SampleSizePerArmMax = NA_integer_,
responseProbControl = NA_real_,
responseProbTreatments = NA_real_,
toxicityProbTreatments = NA_real_,
corrEfficacyToxicity = 0,
corrEfficacyTTE = 0,
hazardRateControl = NA_real_,
hazardRatioTreatments = NA_real_,
totalNumberOfEvents = NA_integer_,
studyDurationPhase3 = NA_real_,
toxicityWeight = NA_real_,
toxicityUpperLimit = NA_real_,
efficacyThreshold = 0,
safetyThreshold = 0,
useUniformPrior = TRUE,
methods = c("ctbonferroni", "ctdunnett", "ctsimes", "ctpooled", "cer", "tsssd.k",
"tsssd.uk", "tsssd.k.rank", "tsssd.uk.rank", "tsssd.k.ce", "tsssd.uk.ce",
"tsssd.k.rank.ce", "tsssd.uk.rank.ce", "bm.rank", "pe.rank", "naive", "ph3only"),
accrualRatePhase2 = NA_real_,
accrualRatePhase3 = NA_real_,
followupTimePhase2 = 0,
maxNumberOfIterations = 1000,
maxNumberOfRawDatasets = 0,
seed = 0,
nthreads = 0
)The number of subjects per arm enrolled in phase II (stage 1).
The smallest number of subjects per arm
enrolled in phase III (stage 2). Operating characteristics are reported
for every stage 2 sample size from this value to
phase3SampleSizePerArmMax.
The largest number of subjects per arm enrolled in phase III (stage 2).
The probability of a short-term response in the control arm.
A vector of length M giving the
probability of a short-term response for each of the M doses under
investigation. Its length determines M.
A vector of length M giving the
probability of toxicity for each dose under investigation.
The correlation between the latent normal variable for the toxicity endpoint and \(z_B\), where \(z_B\) is the latent normal variable that determines the short-term biomarker endpoint. Use 0 for independent biomarker and toxicity endpoints.
The correlation between the latent normal variable for the long-term time-to-event endpoint and \(z_B\). Use 0 for an independent biomarker and long-term endpoint.
The overall hazard rate for the long-term endpoint in the control arm. It must be positive.
A vector of length M giving the hazard
ratio for each treatment relative to the control arm. The hazard rate in
treatment arm k is
hazardRateControl * hazardRatioTreatments[k]; values below 1
indicate effective treatments.
The target total number of long-term endpoint
events in the selected dose and control arms, including subjects enrolled
in phases II and III. It must be a positive integer no greater than the
combined sample size of those two arms at
phase3SampleSizePerArmMin. When provided, the final analysis is
event-driven and studyDurationPhase3 is ignored.
The duration of phase III, measured from the
opening of phase III enrollment to the final analysis. It must be provided
when totalNumberOfEvents is missing.
The weight placed on the posterior mean toxicity rate in the benefit-risk tradeoff used for dose selection. Use 0 to select on efficacy alone.
The prespecified upper limit for the toxicity rate used in the safety criterion. Use 1 when the safety criterion is not applied.
The threshold for the posterior probability that a dose is superior to the control in short-term response. Use 0 when the efficacy criterion is not applied.
The threshold for the posterior probability that the
toxicity rate of a dose is below toxicityUpperLimit. Use 0 when
the safety criterion is not applied.
Whether to use the uniform Beta(1,1) prior (the default) or the Jeffreys Beta(0.5,0.5) prior for the beta-binomial posterior used in dose selection.
A character vector naming the testing procedures to evaluate
for the confirmatory analysis. Any subset of "ctbonferroni",
"ctdunnett", "ctsimes", "ctpooled", "cer",
"tsssd.k",
"tsssd.uk", "tsssd.k.rank", "tsssd.uk.rank",
"tsssd.k.ce", "tsssd.uk.ce",
"tsssd.k.rank.ce", "tsssd.uk.rank.ce",
"bm.rank", "pe.rank",
"naive", and "ph3only". Restricting the set skips the
corresponding computation entirely, which matters because the methods
differ by orders of magnitude in cost.
The accrual rate per arm during phase II. Arrival times follow a homogeneous Poisson process.
The accrual rate per arm during phase III.
The follow-up time after the last phase II enrollment across all arms. Phase III enrollment opens at that point. Use 0 when dose selection occurs immediately after the last phase II enrollment.
The number of simulated trials.
The number of initial simulation iterations for which to retain subject-level raw data. Set to 0, the default, to skip raw-data retention.
The seed for the random number generator.
The number of threads to use. The default, 0, leaves the
RcppParallel setting unchanged.
A list of operating characteristics. Let ngrid denote
phase3SampleSizePerArmMax - phase3SampleSizePerArmMin + 1, the
number of stage 2 sample sizes examined, and let M denote the
number of doses. The list contains
n1, n2, totalNumberOfEvents,
studyDurationPhase3, numberOfIterations, trueOBD:
The design inputs echoed back, with n2 the vector of stage 2 sample
sizes examined.
selectionProb: A vector of length M giving the probability
that each dose is selected at the end of phase II.
pcs: The percentage of simulated trials selecting the dose with
the largest true benefit-risk tradeoff responseProbTreatments -
toxicityWeight * toxicityProbTreatments.
ave.event: An ngrid by 3 matrix of the average number of
events in the selected dose and the control arm combined, in stage 1,
stage 2, and overall.
methods: The testing procedures evaluated, in canonical order.
byMethod: A named list with one element per evaluated method,
each containing
gpower: A vector of length ngrid giving the generalized
power, the probability of both selecting the true best dose and
rejecting its null hypothesis.
prob.rej.each: An ngrid by M matrix of the
probability of rejecting the null hypothesis for each dose conditional
on that dose being selected.
prob.rej.any: A vector of length ngrid giving the
probability of rejecting any null hypothesis.
disjunctive.power: A vector of length ngrid giving the
probability of rejecting at least one true non-null hypothesis. It is
missing when all treatment hazard ratios equal 1.
conjunctive.power: A vector of length ngrid giving the
probability of rejecting all true non-null hypotheses. It is missing
when all treatment hazard ratios equal 1.
fwer: A vector of length ngrid giving the probability
of rejecting any true null hypothesis.
The method names are
ctbonferroni, ctdunnett, ctsimes, and
ctpooled for the closed testing procedure with the inverse normal
combination of stage 1 and stage 2 p-values, using the Bonferroni,
Dunnett, Simes, and pooled log-rank local tests respectively; cer
for the conditional error rate method;
tsssd.k and tsssd.uk for the original two-stage seamless
design boundaries with known and unknown correlation; tsssd.k.rank
and tsssd.uk.rank for rank-based boundaries based on the effective
number of less efficacious doses; and tsssd.k.ce,
tsssd.uk.ce, tsssd.k.rank.ce, and tsssd.uk.rank.ce
for conditional-error updates of the original and rank-based boundaries.
These updates start from nominal boundaries based
on n1/(n1+n2) and then use the observed stage 1 z-statistic and
observed information fraction;
bm.rank for the Biomarker rank-based Dunnett adjustment for unknown
biomarker-efficacy correlation in Wang et al. formula (3) for stage 1,
along with the p-value combination test at the end of stage 2;
pe.rank for the primary endpoint rank-based Dunnett adjustment for
stage 1, along with the p-value combination test at the end of stage 2;
naive for the
unadjusted log-rank test on the combined stage 1 and stage 2 data; and
ph3only for the unadjusted log-rank test on the stage 2 data only.
Because dose selection uses stage 1 data only, ph3only is based on
data independent of the selection and still controls the familywise error
rate, at the cost of discarding the stage 1 information. naive
reuses the selection data and is anticonservative; it is reported for
reference.
sumdataBIN: One row per iteration and phase II arm, containing
iterationNumber, treatmentGroup, responses,
toxicities, zBiomarker, and selected. Treatment
group 0 is control; its toxicity count and biomarker Z statistic are
missing. These rows reproduce the dose-selection operating
characteristics.
sumdataTTE: One row per iteration and phase III sample size,
containing iterationNumber, selectedDose,
phase3SampleSize, stage 1, stage 2, and total event counts,
stage 1, stage 2, and cumulative log-rank Z statistics for the selected
dose, as well as stage 1 log-rank Z statistics for all individual and
pooled dose groups (e.g., stage1LogRankZ1, stage1LogRankZ2,
stage1LogRankZ12). It also has one reject.<method>
indicator column for every requested method. These rows reproduce
ave.event and the operating characteristics in byMethod.
rawdataBIN (present when maxNumberOfRawDatasets is
positive): Subject-level phase II binary data with iterationNumber,
subjectId, treatmentGroup (0 for control and 1 through
M for doses), response, and toxicity. Toxicity is
missing for the control arm because it is not simulated or used for dose
selection.
rawdataTTE (present when maxNumberOfRawDatasets is
positive): Subject-level time-to-event data with iterationNumber,
subjectId, phase, treatmentGroup,
response, arrivalTime, survivalTime,
timeUnderObservation, and event. Phase 2 includes all
arms; phase 3 includes only the control arm and the selected dose.
Data generation uses a copula-based approach. For each subject, a base
random variable \(z_B \sim N(0,1)\) drives the short-term biomarker
endpoint, shortv. Toxicity is generated from
\(z_S = \rho_{tox}z_B + \sqrt{1-\rho_{tox}^2}z_{S,indep}\) and the
toxicity indicator toxv is obtained by thresholding \(z_S\) at
the specified toxicity probability. The long-term endpoint is generated
from \(z_E = \rho_{eff}z_B + \sqrt{1-\rho_{eff}^2}z_{E,indep}\) as
\(v = -\log(\Phi(z_E))/\lambda\), where \(\lambda =
hazardRateControl\) in the control arm and
\(\lambda = hazardRateControl \times hazardRatioTreatments[k]\)
in treatment arm \(k\). Dose selection uses a beta-binomial model with
independent priors, either uniform Beta(1,1) or Jeffreys Beta(0.5,0.5)
depending on useUniformPrior. A dose enters the acceptable set when
the posterior probability that its response rate exceeds that of the
control is above efficacyThreshold and the posterior probability
that its toxicity rate is below toxicityUpperLimit is above
safetyThreshold. Among the acceptable doses, the one maximizing the
posterior mean benefit-risk tradeoff is selected. When both thresholds are
0, all doses are acceptable.
Phase III enrollment opens followupTimePhase2 after the last phase
II enrollment across all arms, and the final analysis occurs
studyDurationPhase3 later. Subjects whose long-term endpoint has not
occurred by then are censored at the analysis time.
Liyun Jiang and Ying Yuan. Seamless phase II/III design: a useful strategy to reduce the sample size for dose optimization. Journal of the National Cancer Institute. 2023, 115(9):1092-1098.
Ping Gao and Yingqiu Li. Adaptive two-stage seamless sequential design for clinical trials. Journal of Biopharmaceutical Statistics. 2025, 35(4), 565-587.
Cyrus Mehta, Ajoy Mukhopadhyay, and Martin Posch. Graph Based, Adaptive, Multiarm, Multiple Endpoint, Two-Stage Designs. Statistics in Medicine. 2025.
# Overall control-arm hazard rate for the long-term endpoint
hazardRateControl <- log(2) / 15.5
# response rates of the two doses under investigation
pe <- c(0.6, 0.5)
# Hazard ratio versus control for each treatment
hazardRatioTreatments <- c(0.65, 0.70)
sim <- lrsim_bmTrtSel(
phase2SampleSizePerArm = 50,
phase3SampleSizePerArmMin = 113,
phase3SampleSizePerArmMax = 118,
responseProbControl = 0.4,
responseProbTreatments = pe,
toxicityProbTreatments = c(0, 0),
corrEfficacyToxicity = 0,
corrEfficacyTTE = 0.43,
hazardRateControl = hazardRateControl,
hazardRatioTreatments = hazardRatioTreatments,
studyDurationPhase3 = 42.1,
toxicityWeight = 0,
toxicityUpperLimit = 1,
efficacyThreshold = 0,
safetyThreshold = 0,
methods = c("ctbonferroni", "ctdunnett", "ctsimes", "ctpooled",
"cer", "naive", "ph3only"),
accrualRatePhase2 = 3,
accrualRatePhase3 = 6,
followupTimePhase2 = 6,
maxNumberOfIterations = 100,
seed = 314159,
nthreads = 1)
sim$pcs
#> [1] 86
sim$byMethod$ctdunnett$gpower
#> [1] 0.76 0.75 0.76 0.75 0.76 0.76