Part 10 · Module 6

Reporting Survival Analysis

Learn how to report time origins, event definitions, follow-up, Kaplan–Meier estimates, hazard ratios, assumptions, competing risks and publication-ready survival figures.

Learning outcomes

After completing this lecture, you should be able to:

  • Report time origins, events, censoring and follow-up clearly.
  • Present event counts, numbers at risk, survival probabilities and median survival.
  • Report log-rank and Cox results with effect estimates and confidence intervals.
  • Describe proportional-hazards checks and alternatives when violated.
  • Report competing-risk estimands and cumulative incidence correctly.
  • Prepare publication-ready survival tables, figures and reporting paragraphs.

Overview

A survival-analysis report should allow readers to reconstruct:

  • who entered the analysis;
  • when follow-up began;
  • what event was counted;
  • how censoring occurred;
  • how much follow-up was available;
  • how many events occurred;
  • which survival and hazard estimands were reported;
  • whether assumptions were assessed.

A Kaplan–Meier curve or hazard ratio alone is incomplete.

Reporting should follow the relevant study-design guideline, such as CONSORT 2025 for randomised trials [1] or STROBE for observational cohorts [2], together with statistical-reporting guidance.

Downloadable simulated dataset

The shared Part 10 dataset is entirely simulated and contains no real patient information. Download the participant-level CSV, consult the data dictionary and usage notes, or recreate it with the standalone R script.

The latent-time columns are included only to explain the simulation and would not all be observable in a real study. Reported analyses should use the observed time and status variables described in the data dictionary.

Why this matters

Common survival-reporting problems include:

  • no time origin;
  • unclear censoring rule;
  • event counts omitted;
  • median follow-up calculated naively;
  • Kaplan–Meier curves without risk tables;
  • hazard ratios described as risks;
  • proportional hazards not assessed;
  • medians reported when not reached;
  • one minus Kaplan–Meier used for competing risks;
  • curve tails interpreted after nearly everyone has left the risk set.

Transparent reporting is essential because the same numerical output can represent different endpoints and assumptions.

When to use this framework

Use the framework for:

  • trial manuscripts;
  • cohort studies;
  • prognostic studies;
  • competing-risk reports;
  • theses;
  • conference abstracts;
  • evidence tables.

The level of detail may differ, but the endpoint definition and effect measure must remain explicit.

Research question and variables

The reporting framework applies to:

  • the analysis population;
  • time origin;
  • observed event or competing-event type;
  • censoring status;
  • treatment or exposure group;
  • adjustment variables;
  • prespecified landmark times;
  • survival, hazard or restricted-time estimands.

Every reported estimate should be traceable to one clearly defined endpoint and analysis population.

Data structure

A standard right-censored analysis commonly uses one participant-level row containing:

VariableReporting role
Participant identifierConfirms one record per independent unit
TimeDuration from the stated origin
Event statusIdentifies event versus censoring
Group or exposureDefines the primary comparison
CovariatesDefines adjusted-model interpretation
Event typeDistinguishes competing outcomes where relevant

Start–stop data, recurrent events, delayed entry and time-dependent covariates require additional variables and explicit description.

Statistical assumptions

Methods reporting checklist

Endpoint

Report:

  • time origin;
  • event;
  • time unit;
  • censoring rule;
  • delayed entry;
  • recurrent or competing events.

Analysis population

State:

  • randomised or eligible population;
  • exclusions;
  • participants analysed;
  • event count;
  • missing dates or covariates.

Descriptive analysis

Name:

  • Kaplan–Meier estimator;
  • confidence-interval method;
  • landmark times;
  • median-survival method;
  • follow-up summary method.

Group comparison

State:

  • log-rank type;
  • weighting;
  • stratification;
  • sidedness.

Regression

State:

  • model;
  • predictors;
  • units;
  • reference categories;
  • ties method;
  • proportional-hazards assessment;
  • non-linear or time-dependent effects;
  • missing-covariate method.

Competing risks

State:

  • event of interest;
  • competing events;
  • cumulative-incidence estimator;
  • cause-specific or subdistribution model;
  • interpretation.

Results reporting checklist

Report:

  • participants per group;
  • deaths or other events;
  • censored counts;
  • numbers at risk;
  • median survival if estimable;
  • survival at prespecified landmarks;
  • effect estimate with 95% CI;
  • log-rank result where relevant;
  • assumption diagnostics;
  • sensitivity analyses;
  • competing-event incidence.

Data example

Essential survival-reporting values

simulated data

Table 1. Overall-survival summary

MeasureUsual careIntervention
Participants120120
Deaths8064
Censored4056
Median survival22.5 months28.0 months
12-month survival71.7%84.2%
24-month survival45.5%59.5%
36-month survival30.1%43.3%

Table 2. Adjusted Cox model

EffectEstimate95% CIp-value
Intervention versus usual care HR0.650.47 to 0.910.011

Follow-up reporting

Median observed follow-up is not the same as the median of raw observed times, because participants with early events shorten the raw-time distribution.

The reverse Kaplan–Meier method treats censoring as the event for follow-up estimation.

reverse_followup <- survfit(
  Surv(
    overall_time,
    1 - overall_event
  ) ~ 1,
  data = survival_data
)

quantile(
  reverse_followup,
  probs = 0.5
)

In the simulated study, reverse Kaplan–Meier median follow-up is 36 months because administrative censoring is concentrated at the planned study end.

Also report the maximum or interquartile follow-up when informative.

Worked example

Worked reporting workflow in R

make_survival_data <- function(n = 240) {
  id <- seq_len(n)
  group_numeric <- as.integer(id %% 2 == 0)
  age <- 35 + ((7 * id) %% 41)
  stage3 <- as.integer(id %% 3 == 0)

  deterministic_uniform <- function(multiplier) {
    (((id * multiplier) %% 997) + 0.5) / 998
  }

  u_recurrence <- deterministic_uniform(37)
  u_nonrecurrence_death <- deterministic_uniform(73)
  u_postrecurrence_death <- deterministic_uniform(109)
  u_dropout <- deterministic_uniform(149)
  u_dropout_time <- deterministic_uniform(181)

  recurrence_rate <-
    0.035 *
    exp(
      log(0.55) * group_numeric +
      0.025 * (age - 55) +
      0.55 * stage3
    )

  nonrecurrence_death_rate <-
    0.010 *
    exp(
      log(0.85) * group_numeric +
      0.030 * (age - 55) +
      0.40 * stage3
    )

  postrecurrence_death_rate <-
    0.060 *
    exp(
      log(0.85) * group_numeric +
      0.020 * (age - 55) +
      0.25 * stage3
    )

  recurrence_time <-
    -log(u_recurrence) / recurrence_rate

  nonrecurrence_death_time <-
    -log(u_nonrecurrence_death) /
    nonrecurrence_death_rate

  postrecurrence_death_delay <-
    -log(u_postrecurrence_death) /
    postrecurrence_death_rate

  overall_death_time <- pmin(
    nonrecurrence_death_time,
    recurrence_time +
      postrecurrence_death_delay
  )

  dropout_time <- ifelse(
    u_dropout < 0.22,
    12 + 24 * u_dropout_time,
    Inf
  )

  censor_time <- pmin(
    36,
    dropout_time
  )

  overall_time <- pmin(
    overall_death_time,
    censor_time
  )

  overall_event <- as.integer(
    overall_death_time <= censor_time
  )

  competing_time <- pmin(
    recurrence_time,
    nonrecurrence_death_time,
    censor_time
  )

  competing_status <- ifelse(
    recurrence_time <=
      nonrecurrence_death_time &
      recurrence_time <= censor_time,
    1L,
    ifelse(
      nonrecurrence_death_time <
        recurrence_time &
        nonrecurrence_death_time <=
          censor_time,
      2L,
      0L
    )
  )

  data.frame(
    id = id,
    group_numeric = group_numeric,
    group = factor(
      group_numeric,
      levels = c(0, 1),
      labels = c(
        "Usual care",
        "Intervention"
      )
    ),
    age = age,
    stage3 = stage3,
    stage = factor(
      stage3,
      levels = c(0, 1),
      labels = c("Stage II", "Stage III")
    ),
    overall_time = overall_time,
    overall_event = overall_event,
    competing_time = competing_time,
    competing_status = competing_status
  )
}

survival_data <- make_survival_data()

library(survival)

km_fit <- survfit(
  Surv(
    overall_time,
    overall_event
  ) ~ group,
  data = survival_data,
  conf.type = "log-log"
)

logrank_fit <- survdiff(
  Surv(
    overall_time,
    overall_event
  ) ~ group,
  data = survival_data
)

survival_data$age10 <-
  (survival_data$age - 55) / 10

cox_fit <- coxph(
  Surv(
    overall_time,
    overall_event
  ) ~ group + age10 + stage,
  data = survival_data,
  ties = "efron",
  x = TRUE
)

ph_test <- cox.zph(
  cox_fit
)

landmark_summary <- summary(
  km_fit,
  times = c(12, 24, 36),
  extend = TRUE
)

cox_table <- exp(
  cbind(
    hazard_ratio = coef(cox_fit),
    confint(cox_fit)
  )
)

landmark_summary
cox_table
ph_test

Selected reporting values

Deaths: 144 / 240
Log-rank chi-square: 6.00, p = 0.014
Adjusted intervention HR: 0.654
95% CI: 0.470 to 0.909
Cox p-value: 0.011

Final manuscript tables and figures should be generated consistently from the same checked analysis objects.

Publication-ready survival figure

A clean overall-survival plot compares intervention and usual care from 0 to 36 months and includes a number-at-risk table at 0, 12, 24 and 36 months.
Figure 1. A publication-ready survival figure uses a full probability axis, clear time units, distinguishable curves and a number-at-risk table. Credit: NajibMY simulated data.

A strong survival figure should include:

  • clear endpoint in the caption;
  • time origin and units;
  • group definitions;
  • censoring marks where useful;
  • numbers at risk;
  • confidence intervals or separate reporting;
  • sensible follow-up limit;
  • accessibility without colour alone.

Reporting medians

Report the median and 95% CI when estimable.

If not reached, write:

Median survival was not reached during the observed follow-up.

Do not replace it with:

  • mean observed follow-up;
  • maximum time;
  • a model extrapolation without disclosure.

Reporting hazard ratios

Always state:

  • outcome event;
  • reference group;
  • adjustment variables;
  • time scale;
  • proportional-hazards assessment.

Avoid:

Intervention improved survival by 35%.

Prefer:

Intervention was associated with a 35% lower death hazard during follow-up, assuming proportional hazards.

Then provide absolute survival estimates.

Reporting non-proportional hazards

If proportional hazards is violated, do not report one ordinary HR without qualification.

Options include:

  • interval-specific HRs;
  • time-varying coefficient;
  • landmark survival difference;
  • restricted mean survival time;
  • flexible parametric model.

Explain which estimand is primary.

Reporting competing risks

Report:

  • event-of-interest CIF;
  • competing-event CIF;
  • event counts;
  • cause-specific or subdistribution model;
  • hazard type in the table heading.

Avoid:

Recurrence-free survival was 60%

when the analysis actually estimated recurrence cumulative incidence.

Tables and text

Use text for the primary message.

Use tables for:

  • landmark survival;
  • multiple predictors;
  • competing-event estimates;
  • sensitivity analyses.

Do not repeat every risk-table number in prose.

Interpreting survival results

Presenting the methods

Suggested reporting

For randomised trials, apply CONSORT 2025 [1]. For observational cohort studies, apply STROBE [2]. Use statistical-reporting principles such as SAMPL and good-practice recommendations for survival plots [3], [4]. Introductory survival-reporting principles are also summarised by Clark and colleagues [5].

Common mistakes

Knowledge check

What endpoint details must be reported?

Answer and reasoning

Time origin, event definition, time scale and censoring rule.

Why use reverse Kaplan–Meier for follow-up?

Answer and reasoning

It accounts for censoring appropriately rather than letting early events shorten the follow-up summary.

What must accompany a hazard ratio?

Answer and reasoning

The endpoint, reference, adjustment set, confidence interval, time scale and proportional-hazards assessment.

What should appear beneath a Kaplan–Meier plot?

Answer and reasoning

Numbers at risk at clinically meaningful times.

How should competing-risk results be labelled?

Answer and reasoning

By event type and estimand, such as recurrence cumulative incidence or cause-specific hazard ratio.

Key take-home messages

References

  1. Hopewell S, Chan AW, Collins GS, Hróbjartsson A, Moher D, Schulz KF, et al. CONSORT 2025 statement: updated guideline for reporting randomised trials. BMJ. 2025;389:e081123. https://doi.org/10.1136/bmj-2024-081123
  2. von Elm E, Altman DG, Egger M, Pocock SJ, Gøtzsche PC, Vandenbroucke JP, et al. The STROBE statement: guidelines for reporting observational studies. PLoS Med. 2007;4(10):e296. https://doi.org/10.1371/journal.pmed.0040296
  3. Lang TA, Altman DG. Basic statistical reporting for articles published in biomedical journals: the SAMPL guidelines. Int J Nurs Stud. 2015;52(1):5–9. https://doi.org/10.1016/j.ijnurstu.2014.09.006
  4. Pocock SJ, Clayton TC, Altman DG. Survival plots of time-to-event outcomes in clinical trials: good practice and pitfalls. Lancet. 2002;359(9318):1686–1689. https://doi.org/10.1016/S0140-6736(02)08594-X
  5. Clark TG, Bradburn MJ, Love SB, Altman DG. Survival analysis part I: basic concepts and first analyses. Br J Cancer. 2003;89(2):232–238. https://doi.org/10.1038/sj.bjc.6601118

These notes support learning and research planning and do not replace statistical consultation for a specific study.

Report an error in this lecture