| gsSurvPower | R Documentation |
gsSurvPower() computes power for a group sequential survival design
with specified enrollment, dropout, treatment effect, and analysis timing.
Unlike gsSurv() and gsSurvCalendar() which solve for sample
size to achieve target power, gsSurvPower() takes fixed design
assumptions and computes the resulting power. It is meant to compute for
a single set of assumptions at a time; different scenarios are evaluated
with separate calls.
gsSurvPower(
x = NULL,
k = NULL,
test.type = NULL,
alpha = NULL,
sided = NULL,
astar = NULL,
sfu = NULL,
sfupar = NULL,
sfl = NULL,
sflpar = NULL,
sfharm = NULL,
sfharmparam = NULL,
r = NULL,
usTime = NULL,
lsTime = NULL,
testUpper = NULL,
testLower = NULL,
testHarm = NULL,
lambdaC = NULL,
hr = NULL,
hr0 = NULL,
hr1 = NULL,
eta = NULL,
etaE = NULL,
gamma = NULL,
R = NULL,
targetN = NULL,
S = NULL,
ratio = NULL,
minfup = NULL,
method = NULL,
spending = c("information", "calendar"),
plannedCalendarTime = NULL,
targetEvents = NULL,
maxExtension = NULL,
minTimeFromPreviousAnalysis = NULL,
minN = NULL,
minFollowUp = NULL,
informationRates = NULL,
fullSpendingAtFinal = FALSE,
tol = .Machine$double.eps^0.25
)
x |
Optional |
k |
Number of analyses planned, including interim and final. |
test.type |
|
alpha |
Type I error rate. Default is 0.025 since 1-sided testing
is default. Internally divided by |
sided |
1 for 1-sided, 2 for 2-sided testing. Used to convert
|
astar |
Lower bound total crossing probability for |
sfu |
Upper bound spending function (default |
sfupar |
Parameter for |
sfl |
Lower bound spending function (default |
sflpar |
Parameter for |
sfharm |
Spending function for the harm bound, used with
|
sfharmparam |
Real value, default |
r |
Integer grid parameter for numerical integration (default 18). |
usTime |
Upper spending time override; vector of length |
lsTime |
Lower spending time override; vector of length |
testUpper |
Indicator of which analyses include an efficacy test.
|
testLower |
Indicator of which analyses include a futility test.
|
testHarm |
Indicator of which analyses include a harm bound.
|
lambdaC |
Scalar, vector, or matrix of control event hazard rates. Rows = time periods, columns = strata. |
hr |
Assumed hazard ratio (experimental/control) for power computation. This is the "what-if" treatment effect. |
hr0 |
Null hazard ratio. Set |
hr1 |
Design alternative hazard ratio used to calibrate futility bounds
( |
eta |
Scalar, vector, or matrix of control dropout hazard rates. |
etaE |
Experimental dropout hazard rates; if |
gamma |
Scalar, vector, or matrix of enrollment rates by period (rows) and strata (columns). |
R |
Scalar or vector of enrollment period durations. |
targetN |
Target total sample size. When specified, |
S |
Scalar or vector of piecewise failure period durations; |
ratio |
Randomization ratio (experimental/control). Default 1. |
minfup |
Minimum follow-up time. |
method |
Sample-size variance formulation. One of
|
spending |
One of |
plannedCalendarTime |
Calendar times for analyses (time 0 = start of
randomization). Scalar (recycled) or vector of length |
targetEvents |
Target number of events at each analysis. Scalar
(recycled), vector of length |
maxExtension |
Maximum time extension beyond the floor time to wait
for |
minTimeFromPreviousAnalysis |
Minimum elapsed time since the previous
analysis. Scalar or vector of length |
minN |
Minimum total sample size enrolled before analysis can proceed.
Scalar or vector of length |
minFollowUp |
Minimum follow-up time after |
informationRates |
Numeric vector of length |
fullSpendingAtFinal |
Logical. When |
tol |
Tolerance for |
Accepting a gsSurv object:
An optional gsSurv-class object x provides defaults for all
parameters. This includes output from gsSurv() and
gsSurvCalendar(). User-specified parameters override these defaults,
enabling "what-if" analyses: e.g., gsSurvPower(x = design, hr = 0.8)
evaluates power under HR = 0.8 using all other parameters from the design.
When x is not provided, all design parameters must be specified
directly.
Hazard ratio roles:
Two distinct hazard ratios serve different purposes. hr is the
assumed treatment effect under which power is evaluated.
hr1 is the design alternative used to calibrate futility bounds
(for test.type 3, 4, 7, 8). It is not used for test.type
5 or 6 (which use H0 spending for the lower bound) or for harm bounds.
When x is provided, hr1 defaults
to x$hr, so futility bounds remain calibrated to the original design
even when power is evaluated under a different hr.
Analysis timing:
Analysis times are determined by per-analysis criteria. Each timing parameter
can be a scalar (recycled to all k analyses), a vector of length
k, or NA at position i to indicate the criterion does
not apply to analysis i.
The choice between plannedCalendarTime and targetEvents has an
important consequence for sensitivity analyses:
plannedCalendarTime fixes calendar times; expected events are
recomputed under the assumed HR. A worse HR produces more events at the
same calendar time (the experimental arm fails faster). This gives an
"unconditional" power.
targetEvents fixes event counts; calendar times adjust. Since
events are held constant, information fractions do not change with HR, and
results match the gsDesign power plot
(plot(x, plottype = 2)) to numerical precision.
How criteria combine within a single analysis:
For analysis i, the analysis time T[i] is determined as:
Compute floor times from applicable criteria:
plannedCalendarTime[i],
T[i-1] + minTimeFromPreviousAnalysis[i], and
time when minN[i] enrolled + minFollowUp[i].
floor_time = max(all applicable floor times).
If targetEvents[i] is specified: find t_events when
expected events reach target. If t_events <= floor_time, analysis
at floor_time. If t_events > floor_time and
maxExtension[i] is set, analysis at
min(t_events, floor_time + maxExtension[i]). Otherwise, analysis
at t_events.
If no targetEvents: analysis at floor_time.
maxExtension is a hard cap: the analysis time is never pushed
beyond plannedCalendarTime[i] + maxExtension[i] (or
T[i-1] + maxExtension[i] when no calendar time is specified),
even if other criteria such as minTimeFromPreviousAnalysis
or minN + minFollowUp would require a later time.
Normalization and consistency:
When x is provided, x$n.fix is used for the
gsDesign::gsDesign() call to ensure the internal drift parameter
\theta and bounds match the original design exactly.
The assumed HR's drift is obtained by scaling:
\theta_{\mathrm{assumed}} = \theta_{\mathrm{design}} \times
|\log(\mathrm{hr}/\mathrm{hr}_0)| / |\log(\mathrm{hr}_1/\mathrm{hr}_0)|.
Power is computed via gsDesign::gsProbability() with actual expected
events as n.I. At the design HR, this reproduces the design power
exactly.
Stratified targetEvents:
targetEvents accepts a scalar (recycled), a vector of length k
(overall targets per analysis), or a matrix with k rows and
nstrata columns (per-stratum targets). A vector of length k
is always interpreted as overall targets; use a matrix for per-stratum
specification.
Bound recalculation when parameters change:
When x is provided, the handling of bounds depends on which
parameters change relative to the original design:
No bound parameters changed (same alpha, sfu,
sfupar) and timing matches: both bounds are reused from x
exactly.
Upper-bound parameters changed (alpha, sfu,
or sfupar) but timing matches: new efficacy bounds are computed
via gsDesign(test.type = 1) at the new alpha, while the
original futility bounds from x are preserved. Any futility
bound that exceeds the new efficacy bound is clipped. This follows
the same convention as gsBoundSummary(). Lower-bound spending
settings from x are intentionally kept in this branch, which
avoids complications with astar validation for binding types.
Timing changed (different target events or calendar
times): both bounds are recomputed from scratch using the full
test.type and all spending parameters.
An object of class c("gsSurv", "gsDesign") containing:
k |
Number of analyses. |
n.I |
Total expected events at each analysis. |
timing |
Information fractions at each analysis. |
T |
Calendar times of analyses. |
eDC, eDE |
Expected events by stratum (control, experimental). |
eNC, eNE |
Expected sample sizes by stratum (control, experimental). |
upper, lower |
Bounds and crossing probabilities. |
harm |
Harm-bound information when |
en, theta |
Expected sample size summary and drift values returned by
|
hr, hr0, hr1 |
Assumed, null, and design hazard ratios. |
power |
Overall power (sum of upper-bound crossing probabilities under the assumed HR). |
beta |
Type II error ( |
variable |
Always |
test.type, alpha, sided, method, spending, call |
Design settings used for the power calculation. |
testUpper, testLower, testHarm |
Logical indicators of which analyses include each bound type, when relevant. |
lambdaC, etaC, etaE, gamma, R, S, ratio, minfup |
Rate and timing inputs used in the calculation. |
vignette("gsSurvPower", package = "gsDesign") for
worked examples including calendar spending, stratified event targets,
and biomarker subgroup analyses.
vignette("gsSurvBasicExamples", package = "gsDesign") for deriving
survival sample size designs and vignette("SeqDesignSurvival",
package = "gsDesign") for reproducing SAS PROC SEQDESIGN survival output.
gsSurv, gsSurvCalendar,
gsDesign, gsProbability
# Create a design, then evaluate power at the design HR
design <- gsSurv(
k = 3, test.type = 4, alpha = 0.025, sided = 1, beta = 0.1,
lambdaC = log(2) / 12, hr = 0.7, eta = 0.01,
gamma = 10, R = 16, minfup = 12, T = 28
)
pwr <- gsSurvPower(x = design, plannedCalendarTime = design$T)
pwr$power # should be 0.9
# Power under a worse HR
gsSurvPower(x = design, hr = 0.8, plannedCalendarTime = design$T)$power
# Event-driven timing (matches gsDesign power plot)
design_events <- design$n.I
gsSurvPower(x = design, hr = 0.8, targetEvents = design_events)$power
# Without a reference design
gsSurvPower(
k = 2, test.type = 4, alpha = 0.025, sided = 1,
lambdaC = log(2) / 6, hr = 0.65, eta = 0.01,
gamma = 8, R = 18, ratio = 1,
plannedCalendarTime = c(24, 36)
)$power
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.