Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • New package on SSC: -finegray- Fast Fine-Gray competing risks regression

    I'd like to announce finegray, a new package for Fine-Gray competing risks regression, now available from SSC.

    To install:
    Code:
        ssc install finegray
    finegray fits the Fine and Gray (1999) subdistribution hazard model for competing risks data. It estimates subdistribution hazard ratios (SHR) that quantify the effect of covariates on the cumulative incidence function in the presence of competing events.

    The implementation uses a Mata forward-backward scan algorithm (Kawaguchi et al. 2021) that avoids data expansion entirely. It produces identical point estimates and log-likelihoods to stcrreg but runs much faster, especially on larger datasets. It is roughly 40x faster at N=500 and 650x faster at N=10,000 (see finegray help in Stata for more on this).

    The package includes three commands:
    - finegray: Fine-Gray subdistribution hazard regression
    - finegray_predict: Post-estimation predictions (linear predictor, CIF, Schoenfeld residuals)
    - finegray_phtest: Test proportional subdistribution hazards assumption

    Features include full factor variable support (i., c., ##), stratified censoring distributions, clustered and model-based standard errors, left-truncated (delayed entry) data, CIF prediction at arbitrary time points, and compatibility with margins.

    Quick example:
    Code:
        webuse hypoxia, clear
        gen byte status = failtype
        stset dftime, failure(dfcens==1) id(stnum)
        finegray ifp tumsize pelnode, compete(status) cause(1)
        finegray_predict cif_hat, cif
        finegray_phtest
    The package has been cross-validated against stcrreg, R's cmprsk::crr, and R's fastcmprsk::fastCrr, confirming agreement in coefficients, standard errors, log-likelihoods, and cumulative incidence functions.

    Requires Stata 16 or later.

    References:
    Fine JP, Gray RJ. A proportional hazards model for the subdistribution of a competing risk. JASA 1999; 94(446): 496-509.
    Kawaguchi ES, Shen JI, Suchard MA, Li G. Scalable algorithms for large competing risks data. Journal of Computational and Graphical Statistics 2021; 30(3): 685-693.

    If you find any bugs or have any feature requests, please submit them at https://github.com/tpcopeland/Stata-Tools/issues.

    Also, please feel free to offer feedback on other packages in my Stata-Tools GitHub. I plan on releasing some of the ones that are most useful on SSC in the near future when I feel I've adequately tested them. In particular, I feel the following packages might be of interest to many of you: tabtools, tvtools, codescan, consort, datamap, and eplot.

  • #2
    Great stuff, thank you Dr Copeland.
    I suggested some ideas for the package on GitHub -- not sure if I did it correctly, first time on there!

    Comment


    • #3
      Thank you for the new package which is very fast compared to stccrreg. When one uses the "finegray_predict cif_hat, cif " command such as in the example provided above, i am confused about what time point this prediction relates to. For instance, is it the predicted CIF after t=1, t=2, t=3, etc? For stcrreg, the standard approach is to use "predict, basecif" command/option to predict the baseline CIF at time points observed in the dataset. From here one can calculate the predicted CIF for each participant/individual in the dataset for relevant timepoints. In the documentation for the new "finegray_predict" command, there doesnt seem to be any reference to what time point the predicted CIF relates to. Can you clarify? apologies if i am missing something obvious.

      Comment


      • #4
        First, my apologies for the slow reply here! I've turned on the email notifications for Statalist replies. Thank you all for your patience, and thank you for the thoughtful questions and suggestions. They shaped my updated release. I responded in much greater detail to Jeffrey's and Hamish's specific questions on the GitHub issue tracker, and I'd point anyone following along there for examples and the methodological reasoning: https://github.com/tpcopeland/Stata-Tools/issues/1

        The short version is that everything raised has now been addressed in finegray 1.1.0, which is live on GitHub and heading to SSC shortly.

        What's new in 1.1.0

        1. Datasets with multiple records per subject are now supported.
        The earlier version blocked these, which was more conservative than necessary. finegray now accepts subjects contributing more than one in-sample record, delayed entry / left truncation via stset (start, stop] intervals, or stsplit data, as long as the model covariates are constant within id(). It detects the multiple records, verifies the covariates are fixed within subject, checks the intervals are contiguous, and internally reduces each subject to one risk-set unit (earliest entry, latest exit, final status), printing a note as it does so. Genuinely time-varying covariates remain deliberately unsupported, because the subdistribution hazard is not well-defined with them (the same reason stcrreg has no tvc() option); in that case you get a clear message pointing to cause-specific stcox.

        2. A new CIF-curve postestimation command, finegray_cif — the stcurve, cif analogue, and then some. It plots the predicted cumulative incidence curve over the full follow-up axis for a chosen covariate profile (at(var=# ...), default the estimation-sample means), and, unlike stcurve, it can draw a pointwise confidence band (analytic influence-function based, on the complementary log-log scale, with an optional exact bootstrap()/seed() cross-check). saving() writes the numeric estimates (time cif se lci uci) to a dataset (the outfile analogue), and timepoints() evaluates on a custom grid, so the graph is never a dead end.

        3. Fixed-horizon (e.g. 5-year) CIF prediction with confidence intervals, by two routes:
        • finegray_cif, attime(1 2 3 5) ci reports a table of the CIF at each listed horizon for a covariate profile, each with a CI — the direct "5-year cumulative incidence with a CI" reportable number.
        • finegray_predict newvar, cif timevar(tvar) ci produces one column holding every subject's predicted CIF at a common horizon, holding each subject's own covariates, with per-subject confidence limits.
        4. Clarified what finegray_predict, cif predicts. To answer Hamish's question directly: by default finegray_predict cif_hat, cif evaluates each subject's predicted CIF at that subject's own analysis time _t; one covariate-adjusted prediction per subject, not a single fixed horizon and not the baseline CIF. The help file now spells this out, and timevar() lets you evaluate at any common horizon instead. The GitHub issue has the full walk-through, including how to read the baseline step function from e(basehaz).

        Installing 1.1.0 now


        Code:
         
         capture ado uninstall finegray 
        Code:
         net install finegray, from("https://raw.githubusercontent.com/tpcopeland/Stata-Tools/main/finegray") replace 
        The SSC copy is currently 1.0.0; I'll be pushing 1.1.0 to SSC within the next week or two, so an adoupdate / ssc install finegray, replace will pick it up shortly. In the meantime the GitHub install above gives you the full 1.1.0 feature set.

        Comment


        • #5
          thanks for the update. FYI I just downloaded the Github version. FYI There seem to be quite a few typos in the help file when viewed via -help finegay- (esp. in Remarks section) -- characters seem omitted

          Comment


          • #6
            Originally posted by Stephen Jenkins View Post
            thanks for the update. FYI I just downloaded the Github version. FYI There seem to be quite a few typos in the help file when viewed via -help finegay- (esp. in Remarks section) -- characters seem omitted
            Thanks Stephen, I'm actually seeing what you're seeing too, but it's a rendering problem in the help file viewer, because when I go to check the underlying .sthlp file the text is correct. For example, I see "Against stcrreg, coeffi atch within" in the help viewer, but in the actual text editing view in a regular text viewer it's correct: "Against {cmd:stcrreg}, coefficients match within"

            I'll try to figure it out before submitting to SSC.

            Comment


            • #7
              finegray 1.3.2 is now live on SSC!

              My thanks first to Kit Baum for processing both the original submission and this update. Thanks also to Jeffrey Chan for the suggestions on GitHub, to Hamish Innes for the question about what finegray_predict, cif evaluates, and to Stephen Jenkins for catching the garbled text in the help viewer. All three shaped this release.

              To update from 1.0.0:

              ssc install finegray, replace

              What has changed since 1.0.0:

              1. New command finegray_cif: the stcurve, cif analogue. It draws the predicted CIF curve for a covariate profile (at(var=# ...), default the sample means) with an analytic or bootstrap confidence band, reports the CIF at fixed horizons (attime(1 2 3 5) ci), draws one curve per group with over(), and saves the estimates with saving().

              2. finegray_predict, cif now documents what it evaluates: each subject's predicted CIF at that subject's own _t, with timevar() to use a common horizon instead. This was Hamish's question in #3.

              3. Multiple records per subject, delayed entry via (start, stop] intervals, and stsplit data are accepted, with the covariates checked for constancy within id(). As of 1.3.2, stset without id() is also accepted; each record is then one subject, as in stcrreg, and the fit is identical to the same data declared with id().

              4. Stratified baseline subdistribution hazard via bstrata() (Zhou et al. 2011), and piecewise-constant time-varying effects via tvc() with tsplit(). Both compose with each other and with the variance options.

              5. Weights: pweight and fweight. Also mi estimate, cmdok: support.

              6. Variance: robust, cluster-robust, and a nuisance-adjusted sandwich that accounts for the estimated censoring distribution, including on delayed-entry fits (Zhang, Zhang and Fine 2011). Factor-variable terms work with margins, contrast and pwcompare.

              7. Postestimation additions: baseline subhazard output, Schoenfeld residuals, and predictions on new data after estimates use.

              8. The methods, formulas and the rationale behind each refusal are in a shipped help topic: help finegray_methods.

              9. The help-viewer problem Stephen reported in #5 was not a typo in the files. The Stata Viewer drops characters at wrap boundaries when a paragraph is written as one very long source line. All help files are now wrapped to normal width and render cleanly.

              10. Several checks that used to run without any notification now stop with an error: a record with a missing compete() value is refused rather than dropped, weights that change between fit and postestimation are refused, and a prediction computable for no observation errors instead of returning all missings.

              One breaking change: estimates saved by a build before 1.3.0 are refused with r(301) and need to be refit, and e(covariates) is now e(designvars). Without the new options, e(b), e(V), e(ll) and the baseline hazard are unchanged from 1.0.0.

              Everything is cross-validated against stcrreg and against frozen references from R's cmprsk and fastcmprsk. Bug reports and feature requests remain welcome at https://github.com/tpcopeland/Stata-Tools/issues.

              Comment

              Working...
              X