The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Generalized Competing Event Modeling with gcemod

gcemod

What gcemod does

gcemod estimates covariate effects on omega+ — the ratio of the hazard for an event of interest to the hazard for a competing event — on either the cause-specific (Cox) or subdistribution (Fine-Gray) scale. Confidence intervals and p-values come from the Lunn-McNeil stacked-model construction. Per-subject omega = omega+/(1+omega+) is reported as a descriptive quantity so model-predicted values can be compared with observed ones.

The workflow: (1) fit the GCE model, (2) build a risk score, (3) find cutpoints that maximize the omega+ difference between groups, (4) draw alligator plots of cumulative incidence by group, and (5) check calibration of predicted vs. observed omega+.

Two contrasting cohorts

The package bundles two competing-risks example datasets that illustrate contrasting GCE applications. They are provided for illustration only and do not represent real patients. In hn (head and neck) the event of interest (cancer recurrence) is more frequent than the competing event (omega+ > 1). In prostate the event of interest (distant metastasis or prostate-cancer death) is less frequent than the competing event (other-cause death) (omega+ < 1). Both use status: 0 = censored, 1 = event of interest, 2 = competing event, with time in years.

data(hn)
Ind <- data.frame(event     = as.integer(hn$status == 1),   # recurrence
                  competing = as.integer(hn$status == 2))   # death w/o recurrence
Cov <- hn[, c("age", "smoker", "t_cat", "n_cat", "p16")]

1. Fit the GCE model (cause-specific)

fit <- gcecox(hn$time, Ind, Cov, M = 5, t = 5)
summary(fit)
#> Generalized competing event model [Cox (cause-specific)]
#> Call: gcecox(Time = hn$time, Ind = Ind, Cov = Cov, M = 5, t = 5)
#>   n = 1000;  events of interest = 391;  competing events = 243;  t = 5
#> 
#> --- omega+ ratio (event of interest vs. competing event) ---
#>        exp(coef) (omega+ ratio) lower .95 upper .95 P-value
#> age                     0.93295   0.91310   0.95323 0.00000
#> smoker                  0.71795   0.49232   1.04697 0.08516
#> t_cat2                  1.00580   0.40885   2.47437 0.98995
#> t_cat3                  0.80732   0.33493   1.94596 0.63349
#> t_cat4                  0.90705   0.37726   2.18085 0.82747
#> n_cat1                  1.26583   0.71349   2.24574 0.42031
#> n_cat2                  1.30179   0.84012   2.01715 0.23788
#> n_cat3                  0.91398   0.47167   1.77110 0.78987
#> p16                     0.64152   0.38994   1.05542 0.08053
#> 
#> Lunn-McNeil omnibus test: chi-sq = 49.215, df = 9, p = <1e-04

Each P-value tests whether that covariate shifts omega+ (event of interest vs. competing event); the omnibus test asks the same jointly.

The Fine-Gray version uses the same interface:

fit_fg <- gcefg(hn$time, Ind, Cov, M = 5, t = 5)
summary(fit_fg)

2. Risk score

The linear predictor is stored in fit$riskscore, and per-subject omega+ / omega at time t in fit$omegaplus / fit$omega.

head(data.frame(riskscore = fit$riskscore,
                omegaplus = fit$omegaplus, omega = fit$omega))
#>    riskscore omegaplus     omega
#> 1  0.3111360 2.4611482 0.7110785
#> 2  1.6653168 9.5334700 0.9050645
#> 3  0.5548256 3.1402976 0.7584715
#> 4 -0.5955188 0.9939913 0.4984933
#> 5 -0.1996211 1.4767900 0.5962516
#> 6  0.4918702 2.9486935 0.7467517

3. Cutpoints maximizing the omega+ difference

cuts <- gce_cutpoints(fit, groups = 2, method = "optimal")
cuts$summary
#>   group   n events_of_interest competing_events mean_omegaplus mean_omega
#> 1   Low 484                181              167       1.105913  0.5070653
#> 2  High 516                210               76       3.396035  0.7458401
cuts$cutpoints
#> [1] -0.02022627

4. Alligator plot (cumulative incidence by risk group)

Risk groups are distinguished by color and event types by line type (event of interest solid, competing event dashed) on a single panel.

gce_alligator(fit, groups = cuts)

5. Calibration of predicted vs. observed omega+

gce_calibration(fit, which = "omegaplus", groups = 5)

Discrimination

gce_performance(fit)
#> C-index (event of interest): 0.502 (95% CI 0.471-0.532)  [risk-score orientation flipped]

The competing-dominant contrast: prostate

Running the same workflow on prostate shows the opposite regime. Here the competing event (other-cause death) dominates, so omega+ ratios and the risk score point the other way, and the alligator jaws open with the competing-event CIF on top.

data(prostate)
Ind_p <- data.frame(event     = as.integer(prostate$status == 1),
                    competing = as.integer(prostate$status == 2))
Cov_p <- prostate[, c("age", "psa", "gleason", "t2b", "comorbidity")]

fit_p <- gcecox(prostate$time, Ind_p, Cov_p, M = 5, t = 5)
summary(fit_p)
gce_alligator(fit_p, groups = 2)

References

Lunn M, McNeil D (1995) Applying Cox regression to competing risks. Biometrics 51:524–32.

Carmona R, et al. (2014) Validated competing event model for the stage I-II endometrial cancer population. Int J Radiat Oncol Biol Phys 89:888–98.

Carmona R, et al. (2016) Improved method to stratify elderly patients with cancer at risk for competing events. J Clin Oncol 34:1270–77.

Mell LK, et al. (2019) Nomogram to predict the benefit of intensive treatment for locoregionally advanced head and neck cancer. Clin Cancer Res 25:7078–7088.

Zakeri K, et al. (2020) Predictive classifier for intensive treatment of head and neck cancer. Cancer 126:5263–5273.

Mell LK, et al. (2024) Effects of androgen deprivation therapy on prostate cancer outcomes according to competing event risk. Eur Urol 85:373–381.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.