The Guyot algorithm (2012), explained
What it is: the Guyot, Ades, Ouwens & Welton (2012) algorithm reconstructs individual patient data from two inputs: the digitised coordinates of a Kaplan–Meier curve and the published numbers at risk. It is the standard method for creating pseudo-IPD in meta-analyses and HTA submissions. The paper has over 2,600 citations.
Inputs
- Digitised step points (tk, Sk) along the curve, starting at (0, 1).
- Times ti of the numbers-at-risk table and the counts ni.
- Optionally, the total number of events, which fixes the final interval.
The algorithm, step by step
- Split the curve into intervals at the at-risk table times. Each interval i runs from ti to ti+1 and contains the digitised points in between.
- First guess of censorings: nci = round(ni × S(ti+1)/S(ti) − ni+1).
- Distribute censorings evenly across the interval (the key assumption), giving the censorings between consecutive digitised points.
- Derive events at each point so that the KM estimate reproduces the digitised drop: dk = round(n̂k × (1 − Sk/Ŝlast)), then update the number at risk n̂k+1 = n̂k − dk − ck.
- Adjust and repeat: if the implied n̂ at ti+1 differs from the published ni+1, shift the censoring count by the difference and recompute until they agree.
- Final interval: use the average censoring rate from earlier intervals, or adjust censoring so the total events match the reported count.
- Write out IPD: events at the digitised step times, censorings at the midpoints between points, and anyone still at risk censored at the last time.
Code
In R, the IPDfromKM package (Liu et al. 2021) and reconstructKM implement the algorithm on coordinates you have already digitised. Once you have IPD, the analysis is standard:
library(survival)
ipd <- read.csv("reconstructed_ipd.csv") # arm, time, event
fit <- coxph(Surv(time, event) ~ arm, data = ipd)
summary(fit) # HR, 95% CI
survfit(Surv(time, event) ~ arm, data = ipd) # medians
In Python, lifelines gives the same (CoxPHFitter, KaplanMeierFitter). TrialCurve runs a faithful port of the original algorithm server-side, with guards for degenerate input, and returns the IPD directly from an image.
Assumptions and limitations
- Censoring is uniform within each at-risk interval. This is fine when table times are close together and weaker when they are years apart.
- Events happen exactly at digitised step times, so digitisation precision limits event-time precision.
- With no at-risk table, only the initial N constrains the result and the tail becomes uncertain.
- Validation studies report good agreement with published HRs when the table is available (Saluja et al. 2019: mean HR error 0.0094).
Newer methods
Recent work automates the digitisation step. SurvdigitizeR (2024) traces curves automatically. KM-GPT (2025) and KMGen (2026) combine language models with computer vision. RESOLVE-IPD (2025) extracts from vector PDFs and models censor marks. They all feed a Guyot-style reconstruction; the tool comparison summarises how they differ.
FAQ
Is the Guyot algorithm accepted by NICE and the EU JCA?
Reconstructed IPD from published curves is widely used in NICE submissions and is referenced in the EU HTA practical guideline on direct and indirect comparisons. Assessors expect the digitisation and its validation to be reported.
Why do I get slightly different results each time I digitise by hand?
Click positions vary by a pixel or two, which moves step times and heights. Two independent extractions and comparison with published statistics are the usual safeguards.
Reconstruct IPD from your own figure. Upload a Kaplan–Meier plot and get curves, numbers at risk, pseudo-IPD, hazard ratios and a validation pack. Three figures a month are free.
Try the live demo Browse trial data API docs