Survival Analysis Workflow

The group’s standard route from a cohort table to a defensible time-to-event result, run through jsurvival in jamovi.

The group’s standard route from a cohort table to a defensible time-to-event result, run through jsurvival in jamovi.

What it is

A sequence with decision points, not a single command.

  1. Define the clock. Fix the time origin (surgery date, diagnosis date, treatment start) and the event. Ambiguity here invalidates everything downstream and is not recoverable in analysis.
  2. Code the event correctly. In jsurvival the event variable must be a factor with the event level explicitly specified. The chapter names silent 0/1 coding errors as the single most common mistake in the group — check this before anything else.
  3. Describe before modelling. Kaplan-Meier or Nelson-Aalen with a risk table; log-rank (stratified where appropriate) for unadjusted comparison. Turnbull NPMLE if the data are interval-censored.
  4. Decide on competing events. If a non-trivial fraction of patients experience a competing event, naive KM on cause-specific death overestimates incidence. Switch to cause-specific or Fine-Gray — see Competing Risks.
  5. Model. Cox proportional hazards, with time-varying covariates or effects, AFT, frailty, or landmark analysis as the design demands.
  6. Check proportional hazards. The Schoenfeld test prints by default in jsurvival and the chapter is explicit that Cox hazard ratios should not be reported without it. If PH fails, use time-varying effects or report a time-averaged effect honestly rather than ignoring it.
  7. Plot. Publication-ready KM curves with risk tables, styled consistently via jjstatsplot.

For high-dimensional covariates the module also offers regularised regression (LASSO, Ridge, Elastic Net), survival trees and random survival forests, and gradient-boosted survival. These need their own validation discipline — a machine-learning survival model reported without out-of-sample evaluation is not a result.

A covariate check that belongs before step 5, and is missing above

Do not put treatment received into a prognostic model as a predictor. The steps above say nothing about which covariates are admissible, and this is the omission that bites hardest, because the resulting model looks better rather than worse.

Whether a patient received chemotherapy, radiotherapy or surgery is not known at diagnosis, is recorded during follow-up, and is assigned by indication — so it encodes the clinician’s own prognostic judgement. Two distinct problems follow. The model learns the indication rather than the effect, often with the sign inverted: patients selected for aggressive treatment are the ones with aggressive disease, so “was treated” predicts death. And patients who die very early may never be recorded as treated at all, which makes the variable partly a function of survival time itself — the immortal-time problem in a different guise.

Two independently verified worked examples sit in this repo, which is why this is stated as a rule rather than a caution. MultiSurv uses pharmaceutical and radiation treatment flags among its ten clinical inputs. SurvivalNet uses a radiotherapy flag, and there the damage is visible rather than inferred: its own attribution output ranks that flag fifth from the top of the risk-increasing end, and in its cohort 81.8% of the worst-prognosis molecular subtype were irradiated against 42.8% of the best, with a 44.1% event rate among irradiated patients versus 19.4% among the rest. The model learned that radiotherapy kills.

If the question genuinely is about treatment effect, that is a different design — landmark analysis, IPCW for treatment switching, or a marginal structural model — and jsurvival has the first two. What it is not is a covariate to add to a prognostic model because it improves the c-index.

The general form of the check: for every candidate covariate, ask whether its value was knowable at the time origin fixed in step 1. Anything recorded afterwards is either an outcome, a mediator, or a proxy for one.

Why it matters for my work

Time-to-event outcomes appear in most of the group’s oncology work, and doing this consistently is the stated point of the whole ClinicoPath approach: one implementation, used everywhere, so that consistency across papers beats per-paper novelty.

Turnaround analysis is an under-used application — elapsed time with in-progress cases is censored data, and this workflow handles it correctly where a simple mean does not. See Turnaround Time.

How it connects

jsurvival — the module implementing every step above.

Competing Risks — the decision at step 4, and the one most often skipped.

Turnaround Time — an operational metric that is really censored time-to-event data.

Concordance Index — the metric this workflow stops short of; it holds the Harrell-versus- Antolini choice at step 6 and the evaluation protocol the ML options below step 7 currently lack.

External Validation — a prognostic model is not established until it has been evaluated outside its development cohort.

OncoLens — a contrast rather than a dependency, and the only one in this wiki. Everything on this page is statistical: fit a hazard across a cohort, compare groups, report a concordance. That tool fits a mechanistic growth–death ODE to one patient’s own serial measurements and projects that individual forward. Nothing here needs it, but the distinction between modelling a population and modelling a patient is worth having met once.

Descriptive Tables — the Table 1 that should accompany any survival analysis.

Pancreas Cohorts — the group’s largest family of outcome studies, and the cohort where the competing-risks decision will bite hardest given typical PDAC survival.

jamovi Module Development — the route by which this workflow becomes runnable without a console, and where its reproducibility guarantee comes from: a .omv file records the analysis chain, not just the output.

Open questions

  • Is there a group template recording the time origin and event definition per study? A short standard header would prevent the ambiguity at step 1 — and it now carries a second job. The covariate rule above turns on whether a variable’s value was knowable at the time origin, so the same header that fixes the clock is what makes covariate admissibility checkable rather than a matter of recollection. That upgrades it from documentation hygiene to load-bearing.
  • For the ML survival options, is there an agreed evaluation protocol (nested CV, time-dependent Brier score, c-index with CI)? Not documented. [unverified] Concordance Index sets out what that protocol has to decide — which concordance variant, stratified or pooled, which tie convention (it matters most for exactly the tree-based options listed above, whose predictions tie by construction), and which calibration metric alongside it.
  • None of these models would report what drove them either. Gradient-Based Feature Attribution records that gap and argues the highest-value use is auditing your own model rather than explaining it to readers.
  • Step 6 checks proportional hazards but the workflow offers no route if it fails other than time-varying effects. Discrete-time models drop the assumption entirely; noted on Concordance Index as an option the group does not currently have implemented.