--- title: "Stratified Survival Analysis" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Stratified Survival Analysis} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE ) ``` ## Introduction `singleEventSurvival()` supports two stratifiers: - `gender` - `age_group` If both are requested, the package fits each stratifier separately. It does not build joint strata such as `Female, 65+`. ## Example Data ```{r setup} library(OdysseusSurvivalModule) survivalData <- data.frame( subject_id = 1:12, time = c(20, 35, 42, 50, 63, 70, 74, 85, 91, 105, 118, 140), status = c(1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0), age_years = c(34, 37, 41, 48, 52, 58, 61, 66, 71, 73, 77, 82), gender = c("Female", "Male", "Female", "Male", "Female", "Male", "Female", "Male", "Female", "Male", "Female", "Male") ) ``` ## Gender Stratification ```{r gender-strata} fitGender <- singleEventSurvival( survivalData = survivalData, timeScale = "days", model = "km", strata = "gender" ) names(fitGender) fitGender[["overall"]]$summary fitGender[["gender=Female"]]$summary fitGender[["gender=Male"]]$summary fitGender$logrank_test_gender ``` The log-rank output is stored in `logrank_test_gender`. ## Age-Group Stratification ```{r age-strata} fitAge <- singleEventSurvival( survivalData = survivalData, timeScale = "days", model = "km", strata = "age_group", ageBreaks = list(c(18, 49), c(50, 64), c(65, Inf)) ) names(fitAge) fitAge[["age_group=18-49"]]$summary fitAge[["age_group=50-64"]]$summary fitAge[["age_group=65+"]]$summary fitAge$logrank_test_age_group ``` Age-group labels are generated automatically from `ageBreaks`. ## Using Both Stratifiers ```{r both-strata} fitBoth <- singleEventSurvival( survivalData = survivalData, timeScale = "days", model = "km", strata = c("gender", "age_group"), ageBreaks = list(c(18, 49), c(50, 64), c(65, Inf)) ) names(fitBoth) fitBoth$logrank_test_gender fitBoth$logrank_test_age_group ``` In this case the result includes: - one entry per observed gender level - one entry per observed age group - `overall` - the relevant `logrank_test_*` tables ## Extract Stratum-Specific Curves ```{r stratum-curves} femaleCurve <- fitGender[["gender=Female"]]$data olderCurve <- fitAge[["age_group=65+"]]$data head(femaleCurve) head(olderCurve) ``` ## Plot Separate Strata ```{r plot-strata} plot( fitGender[["gender=Female"]]$data$time, fitGender[["gender=Female"]]$data$survival, type = "s", col = "firebrick", xlab = "Time (days)", ylab = "Survival probability", ylim = c(0, 1), main = "Gender-specific Kaplan-Meier curves" ) lines( fitGender[["gender=Male"]]$data$time, fitGender[["gender=Male"]]$data$survival, type = "s", col = "steelblue" ) legend( "topright", legend = c("Female", "Male"), col = c("firebrick", "steelblue"), lty = 1, bty = "n" ) ``` ## Stratified Cox and Parametric Fits The same stratification behavior applies to other models. ```{r stratified-other-models} fitCox <- singleEventSurvival( survivalData = survivalData, timeScale = "days", model = "cox", covariates = c("age_years"), strata = "gender" ) fitWeibull <- singleEventSurvival( survivalData = survivalData, timeScale = "days", model = "weibull", covariates = c("age_years"), strata = "age_group", ageBreaks = list(c(18, 49), c(50, 64), c(65, Inf)) ) fitCox[["gender=Female"]]$summary fitWeibull[["age_group=65+"]]$summary ``` ## Summary For stratified analysis, the main points are: 1. Use `strata = "gender"`, `strata = "age_group"`, or both. 2. Read stratum-specific results from named list entries. 3. Use `logrank_test_gender` and `logrank_test_age_group` for between-group tests. 4. Treat gender and age-group results as separate stratified analyses, not joint cells.