---
title: "chestR workflow: global Cox to local biomarker maps"
author: "Richard Jackson"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{chestR workflow: global Cox to local biomarker maps}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 6,
  fig.height = 4.5
)
```

## Overview

**chestR** re-fits a Cox model at each point on a biomarker grid using kernel
weights. Local coefficients show how treatment (and other) effects vary across
biomarker space. The usual workflow is:

1. Fit a global Cox model.
2. Call `chestr()` on biomarker values.
3. Visualise a coefficient with `plot()` / `plot.chestr()`.
4. Optionally run `chestr_test()` for a permutation global test.
This vignette uses a small simulated survival dataset so it builds without
external files.

## Simulate data and fit a global Cox model

```{r simulate}
library(survival)
library(chestR)

set.seed(20250806)
n <- 120
dat <- data.frame(
  trt = rbinom(n, 1, 0.5),
  cov = rnorm(n),
  biom1 = rnorm(n),
  biom2 = rnorm(n)
)

# Mild treatment-effect modification near the origin of biomarker space
lp <- 0.2 * dat$cov +
  log(0.7) * dat$trt *
  exp(-0.5 * (dat$biom1^2 + dat$biom2^2))
dat$time <- rexp(n, rate = exp(lp))
dat$status <- as.integer(dat$time < 4)
dat$time[dat$status == 0L] <- 4

base <- coxph(Surv(time, status) ~ trt + cov, data = dat)
summary(base)$coefficients
```

## Local estimates with `chestr()`

```{r chestr}
biom <- dat[, c("biom1", "biom2")]
cr <- chestr(
  base,
  biom,
  grid.size = 8,
  method = "legacy",
  kern.adj = 2,
  min_events_per_df = 5
)

cr
head(cr$estimates[, c("biom1", "biom2", "trt", "ess_events",
                      "events_per_df", "reliable")])
```

The object has class `"chestr"` and stores:

- `cr$estimates` — local coefficients, SEs, ESS / reliability columns
- `cr$base` — the global Cox model
- `cr$biom` — biomarker data used for weighting and plotting

## Plot local treatment effects

```{r plot}
plot(cr, trt.param = "trt", col.scale = "obs", reliable_only = TRUE)
```

`plot.chestr()` takes everything it needs from `cr` (`base` and `biom` are not
passed again). By default only reliable grid points are drawn.

## Permutation global test

Pointwise local estimates from `chestr()` are descriptive. Formal evidence that
the local treatment surface is not flat can be assessed with
`chestr_test()`, which permutes treatment labels and recomputes `T_L2` and
`T_MAX`.

```{r test, eval = FALSE}
cr <- chestr(
  base, biom,
  grid.size = 8, method = "legacy", kern.adj = 2,
  min_events_per_df = 5,
  treat_term = "trt"
)
# data, treat_term, and fit settings come from cr:
tst <- chestr_test(cr, B = 99, seed = 1)
tst
```

## Session info

```{r session}
sessionInfo()
```
