Changes in version 3.9.0.9006 New features - Added 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). - Added 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). - New sfharm and sfharmparam parameters control the spending function for the harm bound independently from efficacy and futility spending (@keaven, #237). - All six plot() types, gsBoundSummary(), print(), summary(), and xtable() methods support the new three-boundary designs (@keaven, #237). - Added HarmBound vignette demonstrating harm bound design and interpretation (@keaven, #237). - Survival design functions (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). - New 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). - New vignette "Power Computation for Group Sequential Survival Designs" (vignette("gsSurvPower")) with worked examples for sensitivity analysis, alpha reallocation, biomarker subgroup to stratified design, and event-driven timing (@keaven, #109). - Added repeatedPValueBinomialExact() and sequentialPValueBinomialExact() to compute repeated and sequential exact-binomial p-values under spending function designs derived from gsSurv() objects (1922429e). - Added 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). Bug fixes - 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). - Fixed sign inconsistency in 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). - Fixed 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). Documentation - Updated the SeqDesignSurvival vignette to use the one-sided gsSurv() alpha convention when reproducing SAS PROC SEQDESIGN fractional-time survival output (#264). - Corrected and generalized the multi-season rare-event vignette so enrollment timing, planned counts, and simulation event-rate inputs are derived from the stated design specifications, with calendar-timed seasonal analyses, piecewise seasonal failure hazards, and cross-references to the exact binomial vaccine-efficacy vignette (#264). - Expanded 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). - Documented test.type restriction in toBinomialExact(): only test.type = 1 and 4 are supported; other types (including 7 and 8) produce an error (@keaven, #109). - Consolidated shared roxygen2 @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). - New vignette "Selective bound testing at interim analyses" (vignette("SelectiveBoundTesting")) with worked examples for all supported scenarios (@keaven, #255). - Expanded 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). - Clarified the PROC SEQDESIGN survival vignette comparison by using 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). - Added vignette "Multi-season studies for rare events" (vignette("MultiSeasonRareEvents")) demonstrating exact-binomial seasonal monitoring, analysis-time bound updates via toBinomialExact(observedEvents = ...), and blinded information-adaptive enrollment scenarios (1922429e). - Expanded the multi-season vignette with: initial 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). - Reorganized pkgdown article sections to separate general materials, exact binomial workflows, and multiple-hypothesis-testing content (67146132). Testing - Added toInteger() regression tests for selective-bound preservation on gsDesign and gsSurv objects, including test.type 8 with custom harm spending (#261). - Added focused gsSurvPower() regression tests for informationRates, fullSpendingAtFinal, and inherited sidedness behavior from existing time-to-event designs (#258). - Added independent tests for exact-binomial repeated/sequential p-values and for simBinomialSeasonalExact() input validation, reproducibility, and adaptive enrollment behavior (1922429e, c1065ea8). - Added regression test confirming toBinomialExact() one-sided (test.type = 1) updates with observedEvents (1922429e). - Added regression tests for toBinomialExact() usTime/lsTime overrides and selective-futility behavior, plus tests for new futility stopping summary outputs from simBinomialSeasonalExact() (1922429e). - Added regression tests for simBinomialSeasonalExact() stopping summaries, design-based fixed enrollment defaults, and the rare-event toInteger() equal-allocation path (#264). - Expanded nSurv() and gsSurv() regression tests across the supported T/minfup timing combinations for Schoenfeld, Freedman, and Bernstein-Lagakos methods (#270). Changes in version 3.9.0 (2026-02-15) Breaking changes - The R native pipe operator |> is now used throughout the code and documentation, so R >= 4.1.0 is now required (@nanxstats, #236). New features - 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). Improvements - Corrected weighting for stratified time-to-event studies with proportional hazards. This was done for Lachin-Foulkes method, but we also added Bernstein and Lagakos method (@keaven, #243). - print.nSurv() and print.gsSurv() now use refreshed output formatting (@keaven, #243). - C code under src/ is now consistently formatted with clang-format, and C function comments now use Doxygen blocks with clearer parameter and return documentation (@nanxstats, #238). - C normal density calculations now use a shared gs_inv_sqrt_2pi constant from src/gsDesign.h, which now also has include guards, replacing duplicated magic numbers and repeated division (@nanxstats, #241). - Time-to-event design code is now split into focused R/gsSurv-*.R files, improving maintainability and future extension without changing user-facing behavior (@nanxstats, #240). Bug fixes - gsBound() now prints the last two lower boundary values correctly in an internal diagnostic message (atem and atem2) when printerr is enabled (@nanxstats, #238). Testing - Added regression tests for gsBound(), gsBound1(), gsDensity(), and gsProbability() to verify stable behavior after normal density constant refactoring (@nanxstats, #241). - Increased unit test coverage across core gsDesign, spending, and binomial utilities (@keaven, #243). - Updated as_gt() snapshots for gt 1.3.0 LaTeX output changes so tests pass reliably across environments (@nanxstats, #239). Changes in version 3.8.0 (2025-12-07) New features - gsBoundSummary() now displays calendar time for gsNB objects from the gsDesignNB package when analysis times are provided (@keaven, #229, #233). Improvements - plotgsPower() now uses linewidth instead of deprecated size aesthetic for geom_line() calls, avoiding ggplot2 (>= 3.4.0) warnings (@nanxstats, #217). Bug fixes - sfXG3() now correctly reports its name as "Xi-Gallo, method 3" instead of "Xi-Gallo, method 1" (@DMuriuki, #223). - Fixed base plotting for conditional power (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). Testing - Added independent unit tests for sfXG1(), sfXG2(), and sfXG3() (@DMuriuki, #223). - Added independent unit tests for toBinomialExact() and xtable() (@DMuriuki, #224). - Updated as_gt() snapshot tests for gt 1.1.0 compatibility (@nanxstats, #221). - Snapshot files are now included in the built package to satisfy testthat (>= 3.3.0) requirements (@jdblischak, #227). - Reduced visual regression test output verbosity by wrapping base graphics plotting expressions in capture.output() (@nanxstats, #217). Documentation - nNormal() now links to vignette("nNormal") in its See Also section for the full derivation and examples (@keaven, #220). Maintenance - Added workflow_dispatch trigger to R CMD check workflow for easier testing on forks (@jdblischak, #225). Changes in version 3.7.0 (2025-08-25) Breaking changes - 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). Testing - Added independent unit tests for gsAdaptSim() and gsSimulate() (@DMuriuki, #212). - Added independent unit tests for binomialPowerTable() (@DMuriuki, #214). Changes in version 3.6.9 (2025-06-25) Documentation - Added new vignette 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. New features - New function binomialPowerTable() generates power tables across control rates and treatment effects. Supports both analytical calculations and fast simulation for exact results. Changes in version 3.6.8 (2025-05-21) Bug fixes - 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). Testing - Added independent unit tests for as_gt() (@DMuriuki, #196). Documentation - Switched the pkgdown math renderer from KaTeX to MathJaX for improved compatibility, as the MathJaX support was improved in pkgdown 2.1.2 (@nanxstats, #200). - Added Research Organization Registry (ROR) ID to DESCRIPTION (@jdblischak, #201). Changes in version 3.6.7 (2025-03-03) Improvements - All plots in vignettes are now generated by the native SVG device for sharper appearance and fewer package dependencies (@nanxstats, #188). Testing - Add independent unit tests for toInteger() (@DMuriuki, #186). Changes in version 3.6.6 (2025-02-11) New features - gsBoundSummary() gains a new argument alpha to assemble a summary table with multiple efficacy boundaries (@keaven, #183). Testing - Add essential unit tests for gsSurvCalendar() (@keaven, #178). - Refactor graphical tests with vdiffr::expect_doppelganger() (@nanxstats, #176). - Use CODECOV_TOKEN to fix code coverage uploads (@jdblischak, #179). Documentation - Add more details to the parameter r for controlling numerical integration grid points (@nanxstats, #181). Changes in version 3.6.5 (2024-11-14) Improvements - 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. Testing - Add snapshot tests for as_rtf() methods (@DMuriuki, #168). Documentation - Add the cph role to the Authors@R field following best practices (@nanxstats, #166). Changes in version 3.6.4 (2024-07-26) Improvements We have made the spending function summary output more readable and informative. - Text summaries for spending functions with multiple parameters are now properly formatted. For instance, a b = 0.5 1.5 is now displayed as a = 0.5, b = 1.5 (@jdblischak, #162). - The summary() method for sfLDOF() no longer includes the redundant none = 1 in its output (@jdblischak, #159). Documentation - Added a note about using a positive scalar for sfupar in sfLDOF() to create a generalized O'Brien-Fleming spending function (@keaven, 52cc711, 99996b). - Improved math rendering in our pkgdown site vignettes by switching to KaTeX, which is now supported in pkgdown 2.1.0 (@nanxstats, #161). - Standardized vignette titles and headings by using h2 as the base level and adopting sentence case throughout (@nanxstats, #158). Changes in version 3.6.3 (2024-07-09) New features - Implemented conditional error spending functions 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). Improvements - Enhanced eEvents() with input validation to ensure lambda is not NULL (@keaven, 97f629d). Testing - Added independent testing for gsSurvCalendar() (@myeongjong, #144). - Expanded test coverage for gsBinomialExact() (@menglu2, #143). Changes in version 3.6.2 (2024-04-09) Documentation - Add new vignette on conditional power and conditional error, see vignette("ConditionalPowerPlot") (beb2957, 727fe20, 57394fe). - Fix roxygen2 warning and use magrittr pipes in vignette for consistency (#131). Testing - Move independently programmed functions for validation as standard test helper files (#130). Changes in version 3.6.1 (2024-02-13) New features - 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). Improvements - The plotting functions now use dplyr::reframe() to replace dplyr::summarize() when performing grouped cumsum() (@jdblischak, #114). - The plotting functions are updated to use the .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. Documentation - vignettes("SurvivalOverview") is updated with more details and minor corrections (@keaven, #126). - Fix equation syntax in plotting function documentation to render math symbols properly (@keaven, #118). Changes in version 3.6.0 (2023-11-12) Breaking changes - 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). New features - 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). Improvements - 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). - Update the vaccine efficacy, Poisson mixture model, and toInteger vignettes (#105). - Standardize and improve roxygen2 documentation (#104). Changes in version 3.5.0 (2023-07-19) - 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. - Added "A Gentle Introduction to Group Sequential Design" vignette for an introduction to asymptotics for group sequential design. - as_table() and as_gt() methods for gsBinomialExact objects added, as described in the new "Binomial SPRT" vignette. - In 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. - Link update for the gsDesign manual in the documentation, now directly pointing to the gsDesign technical manual bookdown project. - Introduced a new hex sticker logo. Changes in version 3.4.0 (2022-10-12) - Removed restriction on gsCP() interim test statistic zi (#63). - Removed gMCP dependency. Updated vignettes and linked to vignettes in gMCPLite (#69). - Added deprecation warning to hGraph() and suggested using gMCPLite::hGraph() instead (#70). - Moved ggplot2 from Depends to Imports (#56). Changes in version 3.3.0 (2022-05-27) - Addition of vignettes - Demonstrate cure model and calendar-based analysis timing for time-to-event endpoint design - Vaccine efficacy design using spending bounds and exact binomial boundary crossing probabilities - Minor fix to labeling in print.gsProbability - Fixed error in sfStep - Updates to reduce R CMD check and other minor issues Changes in version 3.2.2 (2022-02-02) - Use inherits() instead of is() to determine if an object is an instance of a class, when appropriate - Correctly close graphics device in unit tests to avoid plot output file not found issues - Minor fixes to hGraph() for multiplicity graphs - Minor fix to nBinomial() when odds-ratio scale specified to resolve user issue - Minor changes to vignettes Changes in version 3.2.1 (2021-07-12) - Changed gt package usage in a vignette due to deprecated gt function - Replied to minor comments from CRAN reviewer (no functionality impact) - Minor update to DESCRIPTION citing Jennison and Turnbull reference Changes in version 3.2.0 (2021-03-13) - Substantially updated unit testing to increase code coverage above 80% - Updated error checking messages to print function where check fails - Removed dependencies on plyr packages - Updated github actions Changes in version 3.1.1 (2020-05-07) - Vignettes updated - Added hGraph() to support ggplot2 versions of multiplicity graphs - Eliminated unnecessary check from sequentialPValue - Targeted release to CRAN - Removed dependencies on reshape2, plyr - Updated continuous integration - Updated license Changes in version 3.1.0 - Addition of pkgdown web site - Updated unit testing to from RUnit to testthat - Converted to roxygen2 generation of help files - Converted vignettes to R Markdown - Added Travis-CI and Appveyor support - Added sequentialPValue function - Backwards compatible addition of spending time capabilities to gsDesign and gsSurv Changes in version 3.0-5 - Registered C routines - Fixed "gsbound" - Replaced "array" by "rep" calls to avoid R CMD check warnings Changes in version 3.0-4 - First Github-based release - Cleaned up documentation for nBinomial1Sample() - Updated documentation and code (including one default value for an argument) for nBinomial1Sample() to improve error handling and clarity - Updated sfLDOF() to generalize with rho parameter; still backwards compatible for Lan-DeMets O'Brien-Fleming Changes in version 3.0-3 - Introduced spending time as a separate concept from information time to enable concepts such as calendar-based spending functions. The only user function changed is the gsDesign() function and the change is the addition of the parameters usTime and lsTime; default behavior is backwards compatible. Changes in version 3.0-2 - Simplified conditional power section of gsDesignManual.pdf in doc directory - Corrected basic calculation in gsCP() - Eliminated deprecated ggplot2 function opts() Changes in version 3.0-1 (2016-02-01) - More changes to comply with R standards (in NAMESPACE - importFrom statements - and DESCRIPTION - adding plyr to imports) ensuring appropriate references. - Deleted link in documentation that no longer exists (gsBinomialExact.Rd). - Last planned RForge-based release; moving to Github. Changes in version 3.0-0 - Updated xtable extension to meet R standards for extensions. - Fixed xtable.gsSurv and print.gsSurv to work with 1-sided designs - Update to calls to ggplot to replace show_guide (deprecated) with show.legend arguments where used in ggplot2::geom_text calls; no user impact - Minor typo fixed in sfLogistic help file - Cleaned up "imports" and "depends" in an effort to be an R "good citizen" - Registered S3 methods in NAMESPACE Changes in version 2.9-4 - Minor edit to package description to comply with R standards Changes in version 2.9-3 (2014-11-10) - Added sfTrimmed 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. - Added sfGapped, which is primarily intended to eliminate futility analyses later in a study; see help(sfGapped) for an example - Added summary.spendfn() to provide textual summary of spending functions; this simplified the print function for gsDesign objects - Added sfStep() 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 file - Fixed rounding so that gsBoundSummary, xtable.gsSurv and summary.gsDesign are consistent for gsSurv objects