Fast Survival Analysis and Simulation for Clinical Trials
Overview
Provides fast alternatives to standard survival analysis functions in the 'survival' package, together with tools for time-to-event trial simulation and sequential analysis. The estimation and testing functions cover a single-time-point Kaplan-Meier estimator (survfit_fast()), log-rank tests including weighted and stratified variants (survdiff_fast()), a closed-form hazard ratio estimator based on the Pike-Halley Estimator method (coxph_fast()), restricted mean survival time (rmst_fast()), window mean survival time (wmst_fast()), milestone survival comparison (milestone_fast()), median survival time (medsurv_fast()), the max-combo test (maxcombo_fast()), the robust modestly-weighted log-rank test (rmw_fast()), the weighted Kaplan-Meier (Pepe-Fleming) test (wkm_fast()), the average hazard with survival weight (ahsw_fast()), and the Kalbfleisch-Prentice average hazard ratio (ahr_fast()). Besides vectors, these functions accept a model formula with a data frame, and their results can be returned as data frames. The simulation layer generates individual patient data (simdata_fast()), determines the calendar time of each analysis from combined event and calendar-time rules (cutoff_fast()), performs interim or sequential analyses (analysis_fast()), compares several experimental arms with a shared control (pairwise_fast()), applies treatment switching at progression or after an interim analysis (switch_fast()), and aggregates operating characteristics (simsummary_fast()). A visualization layer assembles design-stage scenarios (gen_scenario_fast()) and builds analysis-stage Kaplan-Meier curves (kmcurve_fast()), each with plot and print methods. All functions are designed for repeated evaluation inside large simulation loops, such as adaptive sample-size re-estimation, probability-of-success calculations, and regional consistency evaluation in multi-regional trials. Core computations are implemented in 'C++' via 'Rcpp' for maximum performance. Methodological background is described in Collett (2014, ISBN:9781439856789).
This release corrects errors and documentation found while preparing an
article on the package. It also adds a formula interface, methods that return
the results as data frames, and two plots.
New features
- The estimation and testing functions and
kmcurve_fast()accept a model formulaSurv(time, event) ~ group(or~ 1for the functions that allow a single group) with a data frame, in place of the vectors of times, event indicators, and group labels;survdiff_fast()andcoxph_fast()also acceptstrata()terms. The control group defaults to the first level of the group variable. The result is that of the vector interface, which is unchanged and remains the choice inside simulation loops. See?formula_interface.
Show all changes in 1.2.0Hide the rest of the changes in 1.2.0
- The results of the estimation and testing functions have the additional class
"fastsurv". Itsas.data.frame()method returns the estimates and tests of any result, including the lists returned bymilestone_fast()andahr_fast(), as rows of a data frame with the columnsterm,estimate,std.error,conf.low,conf.high,statistic, andp.value, so that the results of a loop can be stacked withrbind(). Itscoef()andconfint()methods return the estimates and their confidence limits. Ratios are reported on the log scale. The results are otherwise unchanged. Code that comparesclass()of a result with a single class name should useinherits()instead, andas.data.frame()anddata.frame()of a result, and functions that call them such aswrite.csv(), now return the table described in?as.data.frame.fastsurv; with R 4.3.0 or later they returned the elements of a numeric result as a one-column data frame, whichas.data.frame(unclass(x))still gives. plot.kmcurve_fast()can print the numbers at risk below the survival panel (risk_tableandrisk_times) and draw the pointwise confidence limits as a shaded band (conf.style = "band").as.data.frame()returns the Kaplan-Meier curves of akmcurve_fastobject as a data frame, with the numbers at risk, events, and censored times at each observed time.simsummary_fast()results have aplot()method, which draws the cumulative probabilities of stopping for efficacy and for futility by look, or the stopping probabilities at each look, for every arm and population.
Bug fixes
print.simsummary_fast()failed with an error for a selection of the columns of asimsummary_fast()result, which keeps the class but not the boundary settings, and for a selection of rows without any look row. Such subsets are now printed as ordinary data frames. A selection of rows that keeps only some of the looks, or rows in a different order, paired the boundaries and information fractions with the wrong looks or failed; it is now also printed as an ordinary data frame, and the report is printed only when every block keeps all its looks in their original order. Results combined byrbind(), which keep the boundary settings of the first result only, are printed as an ordinary data frame when the rows of a block differ from those of the first result (for example rows of a population summarized with other boundaries, even under the same population name), instead of pairing them with the boundaries of the first. The boundary columns are labeledEfficacy BoundandFutility Bound, because the statistic need not be a Z-score.- The median survival time of
medsurv_fast()and of the"medsurv"statistic ofanalysis_fast()was infinite when the Kaplan-Meier estimate of a group stayed at 0.5 up to an infinite observed time (subjects withtte = Infat a look that is not reached), and withmethod = "nph"the test then gavez = Infandp = 0. The midpoint of such a stretch is not defined, and the median and the statistics that depend on it are nowNA. The median printed byprint.kmcurve_fast()follows the same rule. simdata_fast()truncated a group size that is a whole number up to rounding error, such as90 * 0.7(62.99999999999999), to the integer below, so the group had one subject fewer, and withfixed.alloc = TRUEand subgroups the C++ kernel wrote past the end of a buffer. The sizes are now rounded, and the kernels check that the fixed subgroup counts add up to the group size. The data simulated for such sizes change. Thensimargument ofsimdata_fast()and thestreamargument ofsimdata_fast()andswitch_fast(), which were truncated in the same way, are now rounded too.- The modestly-weighted log-rank test (
weight = "mwlrt"insurvdiff_fast()andanalysis_fast()) capped the weights at 1, which gives the ordinary log-rank test, when the pooled Kaplan-Meier estimate reached 0 beforet_star(within a stratum for the stratified test). The weights1 / S(t-)are now not capped in this case, as the definition1 / max(S(t-), S(t_star-))and nphRCT imply. analysis_fast()andcutoff_fast()accepted negative event times, which the analysis kernel sorted after all positive times, andanalysis_fast()placed a negative zero (-0) last, unlike the stand-alone functions. Negative times are now an error, and-0is treated as 0.- An event indicator given as a factor with the levels "0" and "1" passed the checks of most functions and was then replaced by its integer codes 1 and 2, which exchanges events and censored observations (for example in
milestone_fast(),ahr_fast(),analysis_fast(), andcutoff_fast()). Factor and character event indicators are now an error.medsurv_fast(),wmst_fast(), andwkm_fast()now also reject non-numeric and negative times, which they sorted as text or accepted. Times of classdifftime, whichis.numeric()does not count as numeric, are rejected by these functions and in thettecolumn ofanalysis_fast()andcutoff_fast(); convert them withas.numeric()in the intended unit. wmst_fast()returned infinite orNaNvalues whentau2was not supplied and each group had an infinite observed time.tau2must now be finite, and an error asks for it when its default is infinite.simdata_fast()with the illness-death model and withoutprevalencedid not checkswitch.prop(a percentage such as 40 made every subject switch) or the length of per-group lists (a third element was ignored). Both are now checked as withprevalence. A multi-armnwith the illness-death model now gives the error message intended for it.gen_scenario_fast()kept a sharede.hazardwhen a scenario gavee.median(and likewise for the other hazard and median pairs), so the printed and plotted scenario used the shared hazard, andsimdata_fast()failed with the merged arguments. A scenario value now replaces the other member of the pair inshared.analysis_fast()reportedNAfor the per-group average hazards of"ahsw"whenever the contrasts were not defined, for example for a group without events up totau. Finite average hazards are now reported, as inahsw_fast().analysis_fast()combined severalstratacolumns through pasted labels, so values containing "." could merge two strata. The columns are now combined through their integer codes.- Clearer errors:
analysis_fast()for an emptymc.rho, aconf.levelthat isNAor not a single value, and aby.subgroupthat is notTRUEorFALSE, and it namesevent.looksortime.looksin the message about non-positive looks;simdata_fast()names the breakpoint argument (d.time,h01.time, and so on) in the messages about piecewise hazards and requires a whole-numbernsim;kmcurve_fast()rejects missing group values. - The weighted Kaplan-Meier test (
wkm_fast()and the"wkm"statistic ofanalysis_fast()) returnedNaNor an infinite weighted difference when an observed time was infinite, for example for a subject without a finite event or dropout time (a cure fraction without dropout) at a look ofanalysis_fast()that is not reached. The integral over the observed range is not defined in this case, and all the statistics are nowNA.
Documentation
maxcombo_fast()andanalysis_fast()now describe the precision of the max-combo p-value correctly. The weights of G(0,1) and G(1,0) add up to the weight of G(0,0), so the correlation matrix of the default weights is singular, and the quasi-Monte-Carlo GenzBretz integral converges slowly: with the defaultmaxptsthe error of the p-value is of the order of 1e-4 rather thanabseps. The statement thatabsepscan be loosened with negligible effect is removed.- The description of
mc.alphainanalysis_fast(), the README, and three vignettes is corrected. The decisions that the Bonferroni bounds settle are those of the exact p-values. The other p-values are integrated as withoutmc.alpha, but the GenzBretz integration uses random numbers, so near the level a decision can differ from that of a run withoutmc.alpha, as it can between two runs with different seeds. The statement that the decisions are the same as with every p-value integrated is removed. - The speed-comparison vignette now gives the ratio of the time per simulated trial with simtrial or TrialSimulator to that with FastSurvival as about two orders of magnitude, because the ratio varies between runs, and states that the one-second timing of 10,000 trials comes from a separate benchmark with a delayed treatment effect.
- The page ranges of Cox (1972) and Gehan (1965) follow the publishers' records (187-202 and 203-224), and the
mrct-regional-consistencyvignette states the result of Homma (2024) for binary outcomes more precisely. Thegroup-sequential-designvignette attributes its planning assumptions to the trial protocol. - The reference to an unpublished manuscript on the Pike-Halley Estimator is removed. The documentation of
coxph_fast()describes the computation. - The documentation of
coxph_fast()and the README describe the correction as a Halley correction expanded to second order, and no longer cite Berry, Kitchin, and Mock (1991) for the statement that the error of the Pike anchor does not vanish with the sample size (their simulation has a fixed sample size). The README no longer quotes a result on thepharmacoSmokingdata that has no source in the package, and describessurvfit_fast()as more than an order of magnitude faster thansurvfit()plussummary(). milestone_fast()defines its three test statistics. The"mover"statistic is obtained by inverting the interval atconf.level, so the statistic and its p-value depend onconf.level(a code comment said the opposite), and the"loglog"statistic is negative when treatment is better. The print methods ofcoxph_fast(),rmst_fast(),milestone_fast(),medsurv_fast(),ahr_fast(),wkm_fast(), andwmst_fast()label the p-value of a one-sided testPr(<z)orPr(>z), and their documentation no longer calls the p-value two-sided.analysis_fast()states that no warning is given whentau,t.eval, orwmst.tau2exceeds the follow-up of a group at a look (the stand-alone functions warn), thatconf.levelapplies to every confidence interval, thatmaxcombo.statandrmw.statdepend onside, that all events at the calendar time of the target event are included, and when the stratified test reduces to the ordinary one within a subgroup.simdata_fast()andswitch_fast()describe the random numbers used whenseedis not supplied, whichset.seed()does not control. The package now requires dqrng 0.4.0 or later, whose default generator is the Xoroshiro128++ generator described in the documentation.simdata_fast()also states the rounding rule offixed.alloc = TRUEand cites Fleischer, Gaschler-Markefski, and Bluhmki (2009) for the maximal-independence model.wkm_fast()explains that the constant and square-root weights can be biased when follow-up differs between the groups, because the curve of the group with shorter follow-up is carried forward.- Vignettes:
compare-logrank-rmstsays that the sample size comes from the Lachin and Foulkes method ofgsDesign::nSurv()(not the Schoenfeld formula);group-sequential-designsays that the trial planned to enroll 482 patients, gives the section of the protocol, and states the type I error for overall survival;correlated-pfs-os-gsdrequires a median overall survival longer than the median progression-free survival;investigate-freidlin-and-kornattributes the parameters of its strong null scenario to Fig. A1 of Freidlin and Korn (2019), which thesimtrialdocumentation also uses; and the computing times are described as they were measured. - Smaller corrections: the variances of the two group shares of
ahr_fast()are equal algebraically (code comments); the example of a zero variance insurvdiff_fast()andrmw_fast(); "orthant" instead of "half-space" for the one-sided max-combo and rMW regions; the left-continuous form of the modestly-weighted weight; "Kalbfleisch and Prentice" and the spelling "Öhrn"; the print-edition ISBN of Collett (2014) inDESCRIPTION; the issue numbers of Gehan (1965) and Tarone and Ware (1977); and the formatting of several references.
Tests
- New tests cover the formula interface of every function (compared with the vector interface), the
as.data.frame(),coef(), andconfint()methods, the numbers at risk and the Kaplan-Meier table of akmcurve_fastobject (compared withsummary()of asurvival::survfit()object and with a hand calculation), and the plot methods. - The one-sided max-combo p-values with three and four weights, whose correlation matrices are singular, are compared with an independent numerical integral that uses this structure.
- New tests cover the printing of subsets of
simsummary_fast()results and the weighted Kaplan-Meier test with infinite times. The tests ofprint.simsummary_fast()are moved to their own file. - A test checks that the switching proportion, the hazard after switching, and the dropout hazard of the illness-death model of
simdata_fast()can differ by subgroup. - New tests cover each bug fix above. The comparisons of the max-combo p-values with the pure-R reference set the seed and use an absolute tolerance, so that they no longer depend on the state left by earlier tests. The rMW p-value is compared with an independent one-dimensional integral. The data generated without
streamare compared with data printed by FastSurvival 1.0.0, beforestreamexisted. A test no longer turns an error ofmedsurv_fast()into a skip, and the error expectations give the expected messages.
From NEWS.md in the release
Install
Health
- OK13 OK2026-08-05
- NOTE12 OK, 1 NOTE2026-08-01
- OK7 OK2026-05-28
Documentation
- Help pages
- 54 (13 internal)includes a package overview page
- Examples that run
- 100%35 run in a plain check
- Exported functions with examples
- 100%
- Documented parameters
- 100%
- Return-value docs
- 100%
- Help pages citing references
- 28%
- Introduction to FastSurvival HTML
- Comparing the log-rank test and RMST under nonproportional hazards HTML
- Group sequential design with the simulation trio HTML
- Group-sequential design with correlated PFS and OS under the Fleischer model HTML
- Investigating the Freidlin and Korn strong null scenario HTML
- MRCT with complex survival analysis design HTML
- Multi-arm trials: K-arm generation and pairwise comparisons against a shared control HTML
- Speed comparison HTML
- Treatment switching and crossover after an interim analysis HTML
- Using your own data generator HTML
Show 1 moreHide 1 vignette
Downloads
Repository
- PRs merged (all time)
- not measured
- Median days to close, 50 most recently updated closed issues
- 3
- Median days to close, 50 most recently updated closed PRs
- not measured
Forks over time
Releases over time
Issues over time
Commits over time
10 development-tooling and community-health practices detected across 6 families in the upstream repository
Checks run against github.com/gosukehommaex/fastsurvival on 2026-10-18.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-10-16 · The repository has a site deploy workflow
pkgdown site last built 2026-10-16
Show all practicesHide 2 practices
Dependencies
Code & Tests
People & History
Pick two releases to compare their code metrics.
- 1.2.0Latest2026-10-15 · current release · diff ↗ ·
listed once in CRAN's queue
Seen in one reading of CRAN's incoming queue, at 2026-10-15 01:08 UTC, so it stayed less than the time between readings. - 1.1.0
- 1.0.02026-09-29 · diff ↗
- 0.2.02026-07-27 · diff ↗ ·
added 14 exports
ahr_fast, ahsw_fast, analysis_fast, gen_scenario_fast, kmcurve_fast, maxcombo_fast, medsurv_fast, milestone_fast, pairwise_fast, rmst_fast, rmw_fast, simsummary_fast, wkm_fast, wmst_fast - 0.1.0first seen 2026-05-27
- RR 4.6.0 released · 2026-04-24
Package metadata
- First seen
- 2026-05-27
- Total releases
- 5 / 1 yrs
- License
- MIT + file LICENSE OSI
- Minimum R
- ≥ 4.1.0
- Download size
- 700 KB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("FastSurvival")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-20, which the citation names so these numbers can be found later. More on citing and the projects behind them.