
Survival Analysis with triageR
Source:vignettes/triageR-survival-analysis.Rmd
triageR-survival-analysis.RmdOverview
Not every clinical outcome is binary. Many research questions are about time to an event, time to death, relapse, readmission, or disease progression — where some patients are followed for the full study and others are “censored” (the event hasn’t happened by the time we stop observing them, or they leave the study early).
This vignette walks through triageR’s survival analysis workflow
using the classic lung dataset (from the
survival package): time to death for patients with advanced
lung cancer.
1. Prepare the data
The lung dataset codes its event status as 1 (censored)
/ 2 (death), a common convention in older survival datasets, but triageR
expects standard 0/1 coding (0 = censored, 1 = event occurred).
lung_clean <- lung
lung_clean$status <- lung_clean$status - 1
lung_clean <- lung_clean[stats::complete.cases(lung_clean), ]
head(lung_clean[, c("time", "status", "age", "sex", "ph.karno")])
#> time status age sex ph.karno
#> 2 455 1 68 1 90
#> 4 210 1 57 1 90
#> 6 1022 0 74 1 50
#> 7 310 1 68 2 70
#> 8 361 1 71 2 60
#> 9 218 1 53 1 702. Fit a survival model
triageR supports two survival engines through the same interface used
for classification models: Cox Proportional Hazards
(the clinical standard, via the survival engine) and
Random Survival Forest (via the aorsf
engine).
Unlike tr_fit(), survival models are fit with
tr_fit_survival(), which expects a time_col
and event_col instead of a single outcome column —
reflecting the different shape of time-to-event data.
model_cox <- tr_fit_survival(
lung_clean,
time_col = "time",
event_col = "status",
engine = "cox_ph"
)
#> Survival model fitted successfully using engine: cox_ph
model_rf <- tr_fit_survival(
lung_clean,
time_col = "time",
event_col = "status",
engine = "survival_rf"
)
#> Survival model fitted successfully using engine: survival_rf3. Validate the model
Survival models are validated with
tr_validate_survival(), which computes the
concordance index (C-index) — survival analysis’s
equivalent of AUC. A C-index of 0.5 means the model is no better than
chance at ranking which patient will experience the event sooner; 1.0
means perfect discrimination.
val_cox <- tr_validate_survival(model_cox, newdata = lung_clean)
#> Survival validation (training_data):
#> C-index: 0.648 (SE: 0.03)
#> N = 167, events = 120
#>
#> Interpretation: C-index of 0.5 = no better than chance; 1.0 = perfect discrimination between patients who experience the event sooner vs. later.
val_rf <- tr_validate_survival(model_rf, newdata = lung_clean)
#> Survival validation (training_data):
#> C-index: 0.839 (SE: 0.018)
#> N = 167, events = 120
#>
#> Interpretation: C-index of 0.5 = no better than chance; 1.0 = perfect discrimination between patients who experience the event sooner vs. later.In this example, the Random Survival Forest achieves a notably higher C-index than Cox Proportional Hazards, suggesting the relationship between predictors and survival time may not be fully linear on the log hazard scale, exactly the kind of finding that motivates comparing more than one modelling approach.
4. Automated pipeline review
tr_agent_review() works with survival models too,
adapting its checks to the time-to-event context: instead of class
imbalance, it checks the event rate (the proportion of
patients who experienced the event rather than being censored), and
events-per-variable is calculated using the number of observed events
rather than total sample size.
review_cox <- tr_agent_review(lung_clean, model_cox, use_agent = FALSE)
#>
#> --- triageR Pipeline Review ---
#>
#> No major issues flagged.5. Generate a TRIPOD+AI-aligned report
tr_tripod_report() supports survival models via the
model_type argument. The report adapts automatically:
instead of a confusion matrix and calibration plot, it reports the
C-index and its standard error.
tr_tripod_report(
model = model_cox,
model_type = "survival",
validation = val_cox,
review = review_cox,
output_file = file.path(tempdir(), "lung_survival_report"),
format = "html"
)Note: automated sensitivity analysis (tr_sensitivity())
is currently only supported for classification models, not survival
models.
Summary
This vignette covered triageR’s survival analysis workflow: preparing time-to-event data, fitting Cox Proportional Hazards and Random Survival Forest models through a consistent interface, validating with the concordance index, running an automated pipeline review adapted for censored data, and generating a TRIPOD+AI-aligned report, all using a real, widely-used clinical dataset.