Guides  /  Cox regression

Cox regression and the hazard ratio

Cox regression adds covariates to survival data and returns a hazard ratio. It is the standard model for time-to-event outcomes, and its central assumption is also the one most often left untested. This guide covers what a hazard ratio actually means, why Cox needs no distribution for survival times, how to test proportional hazards, and what to do when the assumption fails.

Sidra Khan Written and reviewed by Sidra Khan, Lead Biostatistician
Updated 26 October 202611 min read
What is a hazard ratio?

The ratio of the instantaneous event rate in one group to the rate in another, among people still event-free at that moment. A hazard ratio of 0.7 means that at any given time, those remaining in the treated group are having events at 70% of the rate of those remaining in the control group. It is not a risk ratio and it is not a measure of how much longer anyone lives. It describes a rate at an instant, averaged across follow-up.

The model

What Cox regression does

Cox models the hazard, the instantaneous rate of the event among those still at risk, as a baseline hazard multiplied by a factor depending on covariates. The clever part is that the baseline hazard is never estimated. It cancels out of the partial likelihood, so you get covariate effects without committing to any shape for how risk changes over time.

That is why Cox is called semi-parametric, and why it is the default rather than a parametric survival model. You rarely know the true shape of a baseline hazard, and Cox does not make you guess.

What you give up

Because the baseline hazard is never estimated, Cox on its own cannot tell you absolute survival. It gives relative effects. If you need predicted survival at five years you must recover a baseline survival function as a separate step, and that is an extra assumption rather than part of the model output.

Reading the output

Interpreting a hazard ratio

The coefficient is on the log-hazard scale, so the exponentiated coefficient is the hazard ratio. Above 1 means a higher rate of events, below 1 a lower one.

It isIt is not
A ratio of event rates at each instant among survivorsA ratio of risks over the whole period
Averaged over the follow-up actually observedA statement about any particular time point
RelativeInformative about absolute benefit on its own
Dependent on who remains at riskA statement about how much longer people live

The phrase to avoid is "patients lived 30% longer". A hazard ratio of 0.7 says nothing directly about survival time. A large hazard ratio applied to a tiny baseline hazard is still a tiny absolute effect, which is why it should always be reported alongside absolute measures such as survival at fixed time points.

Worked example one

Reading a Cox output table, line by line

A cohort of 410 patients, 78 of whom have the event. Four covariates. This is what the software returns and what each column means.

TermcoefSEHR95% CIzp
Treatment (vs control)−0.35670.14800.7000.524 to 0.936−2.410.016
Age, per year0.04050.01121.0411.019 to 1.0643.62<0.001
Male (vs female)0.22310.16901.2500.898 to 1.7411.320.187
Stage III+ (vs I–II)0.74190.18302.1001.467 to 3.0064.05<0.001

Step 1. Where the hazard ratio comes from

The coefficient is on the log-hazard scale. Exponentiate it.

HR = exp(−0.3567) = 0.700

Treated patients are having events at 70% of the rate of controls, among those still event-free at any given moment.

Step 2. Where the interval comes from

Build it on the log scale, then transform back. Never add and subtract on the hazard ratio itself.

exp(−0.3567 ± 1.96 × 0.1480) = exp(−0.647) to exp(−0.067)
    = 0.524 to 0.936

It excludes 1, consistent with the p-value of 0.016. The asymmetry around 0.700 is expected and correct: ratios are symmetric on the log scale, not the natural one.

Step 3. Continuous covariates need a sensible unit

Age has a hazard ratio of 1.041, which sounds negligible until you notice it is per single year. Rescale it to something a reader can use.

per 10 years: exp(0.0405 × 10) = exp(0.405) = 1.499, 95% CI 1.20 to 1.87

A decade of age raises the hazard by about half. Same model, same data, far more informative presentation. Scale continuous covariates to a meaningful unit before reporting, and say what the unit is.

Step 4. The non-significant term

Sex has a hazard ratio of 1.25 with an interval from 0.90 to 1.74. That is not evidence of no difference, it is a result compatible with anything from a 10% reduction to a 74% increase. With 78 events the study was never going to settle it, and saying "sex was not associated with outcome" overstates what the data can support.

Step 5. Check the events budget before trusting any of it

78 events / 4 covariates = 19.5 events per variable

Comfortably above the usual minimum of ten. Had the model carried twelve covariates, the same 78 events would give 6.5 per variable and every interval above would be narrower than it should be.

Worked example two

What a proportional hazards failure hides

A surgical intervention carries early operative risk and long-term benefit. Suppose the truth is:

months 0–12: HR = 1.80  (worse)
months 12+: HR = 0.60  (better)

What a single Cox model reports

A single hazard ratio is roughly an average of the log hazard ratios, weighted by how many events fall in each period. With events split evenly, 39 in each:

weighted log HR = (39 × ln 1.80 + 39 × ln 0.60) / 78 = 0.038
overall HR = exp(0.038) ≈ 1.04

The model reports a hazard ratio of 1.04 with an interval comfortably spanning 1, and the paper concludes no effect. In reality the intervention nearly doubled the early hazard and cut the later one by 40%. Both findings matter clinically, and the single number erased both.

Why the answer depends on follow-up length

Events early / lateOverall HR reportedConclusion drawn
58 / 20  (short follow-up)1.36"Treatment is harmful"
39 / 39  (balanced)1.04"No effect"
20 / 58  (long follow-up)0.80"Treatment is beneficial"

Same underlying truth, three different published conclusions, decided entirely by how long the study ran. This is why a hazard ratio is described as averaged over the follow-up actually observed, and why that phrase is not a technicality.

What to report instead

Split follow-up at twelve months and give both hazard ratios, each with an interval, stating that the split was chosen because the operative period is clinically distinct rather than because it maximised anything. Add restricted mean survival time at a fixed horizon, which stays interpretable whether or not hazards are proportional.

The assumption

The proportional hazards assumption

Cox assumes the hazard ratio is constant over time. One group may be at higher risk throughout, but the multiple must not change as follow-up proceeds.

Plenty of real situations break this. Surgery carries high early risk and a long-term benefit, so its hazard ratio starts well above 1 and falls below it. A treatment effect that wears off produces a ratio drifting back towards 1. In both cases a single hazard ratio averages opposing effects and can land near 1, reporting "no difference" for an intervention that mattered a great deal at both ends.

Crossing curves are the visible symptom

If the Kaplan-Meier curves cross, proportional hazards has failed and no amount of testing is needed to tell you so. Reporting a single hazard ratio in that situation is not a judgement call, it is a mistake.

Checking

How to test it

✓Scaled Schoenfeld residuals. The standard test. Plot them against time and fit a trend: a slope different from zero indicates a hazard ratio that changes. Available as cox.zph in R and estat phtest in Stata.
✓Log-minus-log plots. Plot log(−log(survival)) against log time by group. Parallel lines support the assumption; converging or crossing lines do not.
✓A time-varying interaction. Add an interaction between the covariate and a function of time. If it is significant, the effect changes over time.
✓Look at the curves. The cheapest check, and the one most likely to be skipped.

Beware the sample size trap in both directions. With a large sample the Schoenfeld test flags trivial departures; with a small one it misses serious ones. Read the plot as well as the p-value.

Remedies

What to do when it fails

ApproachWhen it suits
StratifyThe offending variable is a nuisance you want to adjust for but need no estimate of. Each stratum gets its own baseline hazard, and you get no hazard ratio for that variable.
Time-varying coefficientYou want to describe how the effect changes. Report separate hazard ratios for defined periods, for example 0 to 1 year and beyond.
Split follow-upThere is a natural break, such as a perioperative period. Analyse the intervals separately and say why you chose them.
Restricted mean survival timeYou want a single number that stays valid without proportional hazards. RMST is the average event-free time up to a horizon, and the difference between groups is directly interpretable.
Accelerated failure time modelYou are willing to assume a distribution and want effects on survival time rather than hazard.

Restricted mean survival time is underused and worth knowing about. It answers the question clinicians actually ask, which is how much extra event-free time a treatment buys over a stated period.

Details that matter

Practical matters

✓Events, not sample size, drive power. A common rule is at least ten events per covariate. Two thousand patients with twelve events supports one variable, not twelve.
✓Continuous covariates need a shape. A hazard ratio per unit assumes a straight line on the log-hazard scale. Check it with splines rather than assuming, and avoid categorising a continuous variable purely for convenience.
✓Ties need a method. Efron is a better default than Breslow and most software now uses it. Say which you used.
✓Clustered data needs accounting for. Patients within centres, or multiple events per person, break independence. Use a robust variance or a frailty term, as for any clustered design.
✓Competing risks change the question. With a competing event, a cause-specific Cox model and a Fine-Gray subdistribution model answer different questions. Choose deliberately.

Doing it

In R, SPSS and Stata

R

The survival package is the reference implementation and everything else follows its conventions.

library(survival)
fit <- coxph(Surv(time, status) ~ treatment + age + sex + stage, data = df)
summary(fit)

summary() prints coefficients and exponentiated hazard ratios with intervals in one table. Test the assumption with cox.zph(fit), then plot(cox.zph(fit)) to see the residuals against time, which is more informative than the p-value. For a time-varying effect use tt() inside the formula, and for clustered data add + cluster(centre) for robust standard errors or + frailty(centre) for a random effect.

SPSS

Cox regression sits under Analyze, Survival, Cox Regression. The syntax is:

COXREG time /STATUS = status(1)
  /METHOD = ENTER treatment age sex stage
  /PRINT = CI(95)
  /CRITERIA = PIN(.05) POUT(.10).

SPSS reports Exp(B), which is the hazard ratio, with its interval. It has no direct equivalent of cox.zph, so test proportional hazards by adding a time-dependent covariate through Cox Regression with Time-Dependent Covariates, defining an interaction between the variable and T_.

Stata

Declare the survival structure once with stset, then the model needs no time or status arguments.

stset time, failure(status == 1)
stcox treatment age i.sex i.stage
estat phtest, detail

stcox reports hazard ratios by default; add , nohr for coefficients on the log scale. estat phtest, detail gives the Schoenfeld test per covariate and globally. Use , vce(cluster centre) for clustered data and stsplit to create period-specific effects.

Check the status coding first

Every package needs to know which value of the status variable means the event happened. Coding censoring as 1 and the event as 0 produces a model that runs without complaint and answers the opposite question. Confirm the number of events in the output matches the number you expect before reading anything else.

Avoid these

Six mistakes that cost marks

MistakeWhy it matters
Never testing proportional hazardsThe model's central assumption. If it fails, the single hazard ratio can report no effect for an intervention that mattered in both directions.
Saying "lived 30% longer"A hazard ratio of 0.70 is a ratio of event rates, not of survival times. It says nothing directly about how much longer anyone lived.
Counting participants instead of eventsPower comes from events. Two thousand patients with twelve events supports about one covariate, not twelve.
Reporting a per-unit HR for age1.041 per year looks trivial and is 1.50 per decade. Rescale to a unit a reader can act on.
Treating a wide interval as evidence of no effectAn HR of 1.25 from 0.90 to 1.74 is compatible with meaningful harm. Absence of significance is not absence of effect.
Ignoring clusteringPatients within centres, or repeated events per person, break independence. Use a robust variance or a frailty term.

Writing it up

How to report it

✓Give hazard ratios with confidence intervals, and say what the reference group is.
✓Report the number of events, not only the number of participants.
✓State how proportional hazards was assessed and what the assessment showed.
✓Say which variables were in the model and how they were chosen.
✓Pair relative effects with absolute ones: survival at fixed times, or restricted mean survival time.
✓Name the tie-handling method and the software version.

If an analysis is already written up and you want it checked before submission, proportional hazards is one of the first things a reviewer will look for. An independent statistical review covers it.

Common questions

Frequently asked questions

What is a hazard ratio?

The ratio of the instantaneous event rate in one group to that in another, among people still event-free at that moment. A hazard ratio of 0.7 means the treated group is having events at 70% of the rate of the control group at any given time. It is relative, it is averaged across follow-up, and it says nothing directly about how much longer anyone lives.

Is a hazard ratio the same as a risk ratio?

No. A risk ratio compares cumulative probabilities over a whole period. A hazard ratio compares instantaneous rates among those still at risk, which changes as the at-risk groups change. They are similar when the event is rare and follow-up short, and they diverge otherwise.

What is the proportional hazards assumption?

That the hazard ratio between groups stays constant over follow-up. One group may be consistently worse, but the multiple must not change. It fails when a treatment effect wears off, when there is early harm and late benefit, and whenever survival curves cross.

How do I test proportional hazards?

Scaled Schoenfeld residuals are the standard approach, plotted against time and tested for a trend. Log-minus-log plots should show parallel lines. Adding an interaction between the covariate and time tests it directly. Inspect the plots as well as the p-values, since the test is over-sensitive in large samples and under-sensitive in small ones.

What if the assumption fails?

Stratify on the offending variable if you do not need an estimate for it, fit a time-varying coefficient and report separate hazard ratios by period, split follow-up at a natural break, or switch to restricted mean survival time, which stays interpretable without the assumption.

How many events do I need?

Events drive power, not participants. A widely used rule is at least ten events per covariate, so a study with twelve events can support about one variable regardless of how many people were enrolled. Fitting more produces unstable estimates and overly narrow intervals.