testUpper, testLower, and testHarm parameters to gsDesign(),
gsSurv(), and gsSurvCalendar() for selective bound testing at interim
analyses. Each accepts a logical scalar or vector of length k specifying
which analyses should include that boundary. Inactive bounds are set to
extreme values (±20 on Z-scale) and displayed as NA in print() and
gsBoundSummary() output. This enables designs such as futility-only at
early interims, deferred efficacy testing, or selective harm monitoring
(@keaven, #141).test.type = 7 (binding futility and binding harm bounds) and
test.type = 8 (non-binding futility and non-binding harm bounds) to
gsDesign(), gsSurv(), and gsSurvCalendar(). These three-boundary
designs support monitoring for efficacy, futility, and potential harm
simultaneously, motivated by FDA guidance on overall survival monitoring
in oncology trials (@keaven, #237).sfharm and sfharmparam parameters control the spending function for
the harm bound independently from efficacy and futility spending (@keaven, #237).plot() types, gsBoundSummary(), print(), summary(), and
xtable() methods support the new three-boundary designs (@keaven, #237).HarmBound vignette demonstrating harm bound design and interpretation
(@keaven, #237).nEvents(), nSurv(), gsSurv(),
gsSurvCalendar()) now support hr > hr0 for time-to-event designs
where a larger hazard ratio is the alternative hypothesis. This enables
direct specification of designs for time-to-response, safety endpoints,
or reversed HR conventions. All sample size methods (Lachin-Foulkes,
Schoenfeld, Freedman, Bernstein-Lagakos) and plotting functions handle
both directions symmetrically (@keaven, #251).gsSurvPower() function 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, gsSurvPower() takes fixed assumptions and computes power. Supports
calendar-time and event-driven timing, stratified designs, all test types
(1--8 including harm bounds), and flexible analysis timing criteria
(targetEvents, plannedCalendarTime, maxExtension,
minTimeFromPreviousAnalysis, minN, minFollowUp). When an existing
gsSurv design is provided via x, parameters can be selectively
overridden for "what-if" sensitivity analyses. Changing alpha preserves
original futility bounds (following gsBoundSummary() convention) while
recomputing efficacy bounds (@keaven, #109).gsSurvPower() now supports informationRates to cap spending at planned
versus realized information fractions and fullSpendingAtFinal to force the
final spending fraction to 1 when desired. This makes it easier to evaluate
delayed event accrual while keeping spending tied to a planned information
schedule. It also preserves the original one-sided versus two-sided design
convention when inheriting defaults from an existing gsSurv object (#258).vignette("gsSurvPower")) with worked examples for sensitivity analysis,
alpha reallocation, biomarker subgroup to stratified design, and
event-driven timing (@keaven, #109).repeatedPValueBinomialExact() and sequentialPValueBinomialExact()
to compute repeated and sequential exact-binomial p-values under spending
function designs derived from gsSurv() objects (1922429e).simBinomialSeasonalExact() to run fixed and blinded-adaptive seasonal
rare-event simulations with exact-binomial efficacy monitoring summaries
(1922429e).toBinomialExact() now supports explicit spending-time overrides via
usTime and lsTime (for test.type = 4) to align with gsDesign() and
gsSurv() conventions when updating bounds with observedEvents (1922429e).simBinomialSeasonalExact() now supports usTime/lsTime inputs and
reports futility stopping probabilities (futility_stop_rate with
futility_mc_se) in scenario summaries (1922429e).simBinomialSeasonalExact() now accepts ve = 0 and ve < 0, allowing
null-hypothesis (ve = 0) and non-inferiority margin (ve < 0) scenarios.
Validation now requires only that ve values are finite and less than 1.
A feasibility check verifies that the implied experimental-arm event rates
(control_event_rate * (1 - ve)) remain in [0, 1) (#267).nSurv() and gsSurv() now use the requested survival sample size method
when either T or minfup is NULL. gsSurv() also uses the input
accrual rate and duration when both T and minfup are NULL, solving
follow-up duration against the final group-sequential event requirement.
This allows Schoenfeld survival designs to reproduce SAS PROC SEQDESIGN's
fixed-accrual follow-up solve (#270).simBinomialSeasonalExact() now stops simulated trials at the first
efficacy or futility boundary crossing for reporting stopping time, total
events, and total enrollment, while preserving the non-binding futility
convention for efficacy crossing probability. The simulation also updates
exact-binomial bounds within each trial using the observed total event counts
and defaults fixed per-season enrollment to the design's planned seasonal
enrollment (#264).toInteger() now preserves selective-bound flags (testUpper, testLower,
testHarm) and harm-bound spending (sfharm, sfharmparam for
test.type 7 or 8) when recomputing the design after integer sample
size or event-count rounding. Previously the internal gsDesign() call
omitted these settings, so inactive looks could incorrectly become active
(#261).toInteger() now preserves the intended survival-design behavior that
roundUpFinal = TRUE rounds the final event count up. If the independently
rounded final sample size, using the usual ratio + 1 allocation multiple,
cannot support the integer event target, toInteger() adjusts sample size by
allocation multiples, with a warning, until the target is achievable. Designs
where the rounded sample size already supports the integer event target retain
the previous behavior (#264).toInteger() survival integerization now keeps the calendar design fixed
while deriving interim integer events from timing and final integer event
target. Enrollment is inflated minimally by scaling accrual rates and then
rounded to allocation multiples, avoiding unnecessary calendar-extension-driven
enrollment increases for small final-event rounding changes. A variable-duration
fallback is retained with a warning when fixed-calendar inflation is infeasible
(#271).hrn2z() which used sign(hr0 - hr1)
while zn2hr() used sign(hr1 - hr0), preventing correct round-trip
conversion. Both now use sign(hr1 - hr0) (@keaven, #251).toBinomialExact() one-sided (test.type = 1) updating with
observedEvents so futility-adjustment code is only executed when
test.type = 4 (1922429e).toBinomialExact() now respects selective futility testing (testLower) when
present on a gsSurv object by flattening lower spending at inactive looks
(1922429e).SeqDesignSurvival vignette to use the one-sided gsSurv()
alpha convention when reproducing SAS PROC SEQDESIGN fractional-time
survival output (#264).toInteger() help and vignette guidance for survival-design final
event rounding, final sample-size feasibility adjustment, and seasonal designs
with a final zero event-rate period (#264).test.type restriction in toBinomialExact(): only
test.type = 1 and 4 are supported; other types (including 7 and 8)
produce an error (@keaven, #109).@param documentation using @inheritParams
so that test.type, spending function parameters, and other shared arguments
are defined once in gsDesign() or nSurv() and inherited by gsSurv()
and gsSurvCalendar() (@keaven, #237).vignette("SelectiveBoundTesting")) with worked examples
for all supported scenarios (@keaven, #255).gsSurvPower() documentation and vignette guidance for
informationRates, calendar spending, and fullSpendingAtFinal, including
a corrected worked example of the spending fractions used at the final
analysis (#258).test.type = 2, alpha = 0.025, method = "Schoenfeld", and
T = minfup = NULL to match SAS's symmetric two-sided fixed-accrual
design, and by separating fractional-time output from the SAS ceiling-time
adjusted design (#270).vignette("MultiSeasonRareEvents")) demonstrating exact-binomial seasonal
monitoring, analysis-time bound updates via
toBinomialExact(observedEvents = ...), and blinded information-adaptive
enrollment scenarios (1922429e).gsBoundSummary() output,
IA1-only futility illustration, VE and nominal one-sided p-values at
exact-binomial bounds, and clearer simulation tables including efficacy and
futility stopping probabilities with non-binding Type I interpretation notes
(c1065ea8, 2e9260bd).toInteger() regression tests for selective-bound preservation on
gsDesign and gsSurv objects, including test.type 8 with custom harm
spending (#261).gsSurvPower() regression tests for informationRates,
fullSpendingAtFinal, and inherited sidedness behavior from existing
time-to-event designs (#258).simBinomialSeasonalExact() input validation, reproducibility, and
adaptive enrollment behavior (1922429e, c1065ea8).toBinomialExact() one-sided
(test.type = 1) updates with observedEvents (1922429e).toBinomialExact() usTime/lsTime overrides and
selective-futility behavior, plus tests for new futility stopping summary
outputs from simBinomialSeasonalExact() (1922429e).simBinomialSeasonalExact() stopping summaries,
design-based fixed enrollment defaults, and the rare-event toInteger()
equal-allocation path (#264).nSurv() and gsSurv() regression tests across the supported
T/minfup timing combinations for Schoenfeld, Freedman, and
Bernstein-Lagakos methods (#270).|> is now used throughout the code and
documentation, so R >= 4.1.0 is now required (@nanxstats, #236).nSurv() and gsSurv() now incorporate Schoenfeld and Freedman methods for
sample size and power for time-to-event studies with proportional hazards.
This allows matching versus other software (@keaven, #243).print.nSurv() and print.gsSurv() now use refreshed output formatting
(@keaven, #243).src/ is now consistently formatted with clang-format, and C
function comments now use Doxygen blocks with clearer parameter and return
documentation (@nanxstats, #238).gs_inv_sqrt_2pi constant
from src/gsDesign.h, which now also has include guards, replacing
duplicated magic numbers and repeated division (@nanxstats, #241).R/gsSurv-*.R files,
improving maintainability and future extension without changing user-facing
behavior (@nanxstats, #240).gsBound() now prints the last two lower boundary values correctly in an
internal diagnostic message (atem and atem2) when printerr is enabled
(@nanxstats, #238).gsBound(), gsBound1(), gsDensity(), and
gsProbability() to verify stable behavior after normal density constant
refactoring (@nanxstats, #241).as_gt() snapshots for gt 1.3.0 LaTeX output changes
so tests pass reliably across environments (@nanxstats, #239).gsBoundSummary() now displays calendar time for gsNB objects from the
gsDesignNB package when analysis times are provided (@keaven, #229, #233).plotgsPower() now uses linewidth instead of deprecated size aesthetic
for geom_line() calls, avoiding ggplot2 (>= 3.4.0) warnings (@nanxstats, #217).sfXG3() now correctly reports its name as "Xi-Gallo, method 3" instead of
"Xi-Gallo, method 1" (@DMuriuki, #223).plottype = 4) so labels passed
to text() match the plotted points. This prevents r-devel (R 4.6.0)
truncation warnings and keeps vdiffr snapshots bitwise reproducible
across R versions (@nanxstats, #231).sfXG1(), sfXG2(), and sfXG3()
(@DMuriuki, #223).toBinomialExact() and xtable()
(@DMuriuki, #224).as_gt() snapshot tests for gt 1.1.0 compatibility (@nanxstats, #221).capture.output() (@nanxstats, #217).nNormal() now links to vignette("nNormal") in its See Also section for
the full derivation and examples (@keaven, #220).workflow_dispatch trigger to R CMD check workflow for easier testing
on forks (@jdblischak, #225).hGraph() has been formally removed from gsDesign (@nanxstats, #215).
It was soft-deprecated in gsDesign 3.4.0 and moved to gMCPLite.
Use gMCPLite::hGraph() instead.
This change also preemptively fixes an R CMD check issue with
ggplot2 (>= 4.0.0) that would otherwise require declaring MASS as
an explicit dependency (tidyverse/ggplot2#6578).
gsAdaptSim() and gsSimulate() (@DMuriuki, #212).binomialPowerTable() (@DMuriuki, #214).vignette("binomialTwoSample") for binomial two-arm
trial design and analysis (@keaven, #202). Covers superiority,
non-inferiority, and super-superiority designs using risk-difference methods.
Includes sample size calculations, power analysis, and protocol wording with
both asymptotic approximations and simulation approaches.binomialPowerTable() generates power tables across control
rates and treatment effects. Supports both analytical calculations and
fast simulation for exact results.gsBoundSummary() (as updated in gsDesign 3.6.6) did not consider
spending time for alternate alpha levels when the alpha argument
was specified. This issue has been resolved; lsTime and usTime
are now correctly used for updated bounds with these alternate alpha levels
(@keaven, #203).DESCRIPTION
(@jdblischak, #201).gsBoundSummary() gains a new argument alpha to assemble a summary
table with multiple efficacy boundaries (@keaven, #183).gsSurvCalendar() (@keaven, #178).vdiffr::expect_doppelganger() (@nanxstats, #176).CODECOV_TOKEN to fix code coverage uploads (@jdblischak, #179).r for controlling numerical
integration grid points (@nanxstats, #181).toInteger() (introduced in gsDesign 3.5.0) is updated to match broader,
non-gsDesign conventions for deriving integer sample size and event counts
(@keaven, #172).
This update may result in different outputs compared to previous versions.
Users who use this function should review the updated function documentation
(?toInteger) and vignette("toInteger") for details.
cph role to the Authors@R field following best practices
(@nanxstats, #166).We have made the spending function summary output more readable and informative.
a b = 0.5 1.5 is now displayed as
a = 0.5, b = 1.5 (@jdblischak, #162).summary() method for sfLDOF() no longer includes the redundant
none = 1 in its output (@jdblischak, #159).sfupar in sfLDOF()
to create a generalized O'Brien-Fleming spending function
(@keaven, 52cc711,
99996b).sfXG1(), sfXG2(),
and sfXG3() based on Xi and Gallo (2019).
See vignette("ConditionalErrorSpending") for details and reproduced
examples from the literature (@keaven, #147. Thanks, @xidongdxi,
for comments on vignette).gsSurvCalendar() (@myeongjong, #144).gsBinomialExact() (@menglu2, #143).vignette("ConditionalPowerPlot")
(beb2957,
727fe20,
57394fe).gsBoundSummary() now has the as_rtf() method implemented to generate
RTF outputs for bound summary tables (@wangben718, #107).plotgsPower() gets new arguments offset and titleAnalysisLegend
to enable more flexible and accurate power plots (plottype = 2)
(@jdblischak, #121, #123).dplyr::reframe() to replace
dplyr::summarize() when performing grouped cumsum() (@jdblischak, #114)..data pronoun from rlang
with ggplot2::aes(). This simplifies the code and follows the
recommended practice when using ggplot2 in packages (@jdblischak, #124).hGraph() now uses named guide argument in the scale_fill_manual() call
to be compatible with ggplot2 3.5.0 (@teunbrand, #115).
Note: this function has been deprecated and moved to gMCPLite
since gsDesign 3.4.0. It will be removed from gsDesign in a future version.
Please use gMCPLite::hGraph() instead.vignettes("SurvivalOverview") is updated with more details and
minor corrections (@keaven, #126).gsSurv() and nSurv() have updated default values for T and minfup
so that function calls with no arguments will run. Legacy code with T
or minfup not explicitly specified could break (#105).gsSurvCalendar() function added to enable group sequential design for
time-to-event outcomes using calendar timing of interim analysis
specification (#105).as_rtf() method for gsBinomialExact() objects added,
enable RTF table outputs for standard word processing software (#102).toBinomialExact() and gsBinomialExact(): fix error checking in bound
computations, improve documentation and error messages (#105).print.gsSurv(): Improve the display of targeted events (very minor).
The boundary crossing probability computations did not change.
The need is made evident by the addition of the toInteger() function (#105).toInteger(): Fix the documentation and execution based on the ratio argument (#105).sfPower() now allows a wider parameter range (0, 15].toInteger() function added to convert gsDesign or gsSurv classes
to integer sample size and event counts.toBinomialExact() function added to convert time-to-event bounds to
exact binomial for low event rate studies.as_table() and as_gt() methods for gsBinomialExact objects added,
as described in the new "Binomial SPRT" vignette.plot.ssrCP(), the hat syntax in the mathematical expression is revised,
resolving labeling issues.ggplot2::qplot() usage replaced due to its deprecation in ggplot2 3.4.0.gsCP() interim test statistic zi (#63).hGraph() and suggested using gMCPLite::hGraph() instead (#70).Depends to Imports (#56).inherits() instead of is() to determine if an object is an instance of a class, when appropriatehGraph() to support ggplot2 versions of multiplicity graphssequentialPValuesequentialPValue functiongsDesign and gsSurvR CMD check warningsnBinomial1Sample()nBinomial1Sample() to improve error handling and claritysfLDOF() to generalize with rho parameter; still backwards compatible for Lan-DeMets O'Brien-FleminggsDesign() function and the change is the addition of the parameters usTime and lsTime; default behavior is backwards compatible.gsCP()opts()importFrom statements - and DESCRIPTION - adding plyr to imports) ensuring appropriate references.xtable.gsSurv and print.gsSurv to work with 1-sided designsshow.legend arguments where used in ggplot2::geom_text calls; no user impactsfLogistic help filesfTrimmed as likely preferred spending function approach to skipping early or all interim efficacy analyses; this also can adjust bound when final analysis is performed with less than maximum planned information. Updated help(sfTrimmed) to demonstrate these capabilities.sfGapped, which is primarily intended to eliminate futility analyses later in a study; see help(sfGapped) for an examplesummary.spendfn() to provide textual summary of spending functions; this simplified the print function for gsDesign objectssfStep() which can be used to set an interim spend when the exact amount of information is unknown; an example of how this can be misused is provided in the help filegsBoundSummary, xtable.gsSurv and summary.gsDesign are consistent for gsSurv objects