---
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.
