IPD from Kaplan-Meier curves
Reconstructed patient-level survival data, for comparative and single-arm reviews.
What it is
Most survival outcomes are published only as Kaplan-Meier curves, with hazard ratios reported inconsistently or not at all. The Guyot algorithm rebuilds an approximation of the original patients from the curve: the digitized coordinates and the numbers at risk under the figure are converted back into one row per patient, with a time and an event or censoring.
In a comparative review, the reconstructed patients of every study are pooled and analysed as time-to-event data: Kaplan-Meier curves, a Cox model for the hazard ratio, and a check of proportional hazards. When hazards are not proportional, restricted mean survival time or a landmark analysis replaces a single hazard ratio.
In a single-arm review, reconstruction adds what a pooled proportion cannot: when studies report survival at different time points, or only as a curve, the pooled reconstructed cohort gives one survival curve, the survival at any time point, the median survival and the restricted mean survival time.
preprocess() and getIPD()one row per patient: time, status, arm4. Validate and poolcompare with the reported median, survival rates and eventsWhen to use it
Use it when
- Comparative: studies report survival as Kaplan-Meier curves, but hazard ratios are missing, inconsistent or not adjusted the same way.
- Comparative: the curves cross or separate late, so a single hazard ratio would be misleading.
- Single-arm: few studies report survival at the same time point, and pooled proportions at 1, 3 and 5 years would each rest on very few studies.
- The figures show the numbers at risk, or at least the total number of events.
Choose another tool when
- The curves have no numbers at risk and no reported events: the censoring pattern cannot be recovered and the reconstruction is unreliable.
- Every study reports the same time point and the outcome is a simple rate: pooled proportions are enough (single-arm binary).
- Real individual patient data can be obtained from the authors: use them, with patient-level covariates.
- You need adjustment for patient characteristics: reconstructed data contain only time, event and arm.
Reconstruction, parameter by parameter
Click a highlighted argument to see what it does and which values to use. Picking a value updates the code.
# digitized: data frame with time and survival, one row per click
pre <- preprocess(dat = digitized,
= c(0, 12, 24, 36, 48, 60),
nrisk = c(80, 76, 72, 49, 30, 11),
totalpts = 80,
= 100)
ipd <- getIPD(prep = pre, = 1, = NULL)$IPD
# repeat for every arm of every study, then rbind() them
Comparative analysis, parameter by parameter
The reconstructed patients of both arms, from all studies, analysed together. Click a highlighted argument to see the options.
ipd$arm <- relevel(factor(ipd$arm), ref = "Control")
km <- survfit(Surv(time, status) ~ arm, data = ipd)
cox <- coxph( = Surv(time, status) ~ arm + strata(study),
data = ipd)
cox.zph(cox, = "km") # proportional hazards
survRM2::rmst2(ipd$time, ipd$status,
ipd$arm == "Experimental", = 36)
Single-arm analysis, parameter by parameter
One pooled curve from all the reconstructed cohorts, and the numbers a single-arm review needs. Click a highlighted argument to see the options.
km <- survfit(Surv(time, status) ~ 1, data = ipd)
summary(km, = c(12, 36, 60)) # survival at each time point
print(km, = 60) # median and restricted mean
The Kaplan-Meier plot, parameter by parameter
These arguments change only how the result is shown, not the result itself. Click one to see the options.
ggsurvplot(km, data = ipd,
= c("navyblue", "darkred"),
= TRUE,
= TRUE,
= 12,
= c(0, 60),
xlab = "Time (months)", ylab = "Overall survival")
How to read the results
Validation
- Compare each reconstructed arm with what the paper reports: median survival, survival at fixed times, number of events.
- Overlay the reconstructed curve on the published one; they should be visually indistinguishable.
- Report the validation in the supplement.
Proportional hazards
- Check the Schoenfeld residuals before trusting one hazard ratio.
- If the assumption fails, report RMST or a landmark analysis (before and after a time point).
- Crossing curves are a warning sign even when the test is not significant.
Limitations
- Reconstruction approximates, it does not recover, the original patients.
- No covariates: no adjustment for patient characteristics.
- Accuracy depends on the quality of the figure and on the risk table.
In my work
Pooled reconstructed survival from two published comparative reviews. Click a figure to enlarge it.
pre <- preprocess(dat, trisk = trisk, # risk table
nrisk = nrisk, # at each time
totalpts = n, # patients
maxy = 100) # survival in %
ipd <- getIPD(pre, armID = 1)$IPD # one arm
cox <- coxph(Surv(time, status) ~ treat,
data = ipd_all) # pooled HR
km <- survfit(Surv(time, status) ~ treat,
data = ipd_all) # pooled curves
cox <- coxph(Surv(time, status) ~ treat,
data = ipd_all) # pooled HR
cox.zph(cox, transform = "km") # PH check
References
- Guyot P, Ades AE, Ouwens MJNM, Welton NJ. Enhanced secondary analysis of survival data: reconstructing the data from published Kaplan-Meier survival curves. BMC Med Res Methodol. 2012;12:9.
- Liu N, Zhou Y, Lee JJ. IPDfromKM: reconstruct individual patient data from published Kaplan-Meier survival curves. BMC Med Res Methodol. 2021;21:111.
- Royston P, Parmar MKB. Restricted mean survival time: an alternative to the hazard ratio for the design and analysis of randomized trials with a time-to-event outcome. BMC Med Res Methodol. 2013;13:152.
- Grambsch PM, Therneau TM. Proportional hazards tests and diagnostics based on weighted residuals. Biometrika. 1994;81:515-526.
- Higgins JPT, Thomas J, Chandler J, et al. Cochrane Handbook for Systematic Reviews of Interventions, version 6.5. Cochrane; 2024. Chapter 26 (individual participant data).