PERSUADE

ParamEtRic SUrvivAl moDel sElection

A standardized R tool to support the selection, comparison, and communication of parametric survival models, and their implementation in decision-analytic models.


Overview

PERSUADE guides analysts through a reproducible workflow for survival analysis and model selection. It provides:

The framework is designed for transparency and consistency when survival analysis feeds into decision-analytic models.


Prerequisites

Quick start

To get started, open PERSUADE_example_workflow.R and run its contents in R: file.edit(system.file("example_workflow", "PERSUADE_example_workflow.R", package = "PERSUADE"))

This script:


Step-by-step workflow

1. Load PERSUADE package

library(PERSUADE)

2. Run example analysis

dat <- subset(PERSUADE::nsclc_ipd, dataset_id == "Immunotherapy_OAK_PDL1_unselected")
years  <- dat$time_months / 12  # time to event
status <- dat$event             # event indicator
group  <- dat$arm               # grouping variable


PERSUADE <- f_PERSUADE(
  name = "NSCLC_OS",
  years = years,   # time-to-event
  status = status, # event indicator
  group = group,    # grouping variable
  strata = TRUE,
  spline_mod = TRUE,
  cure_mod = TRUE,
  time_unit = 1/12,              # months in years
  time_horizon = 20,
  time_pred_surv_table = c(0, 1, 2, 5, 10, 20)
)

3. Inspect the object

print(PERSUADE)

4. Summarize results

# Kaplan-Meier estimates
summary(PERSUADE, type = "km")

# Survival probabilities at time points
summary(PERSUADE, type = "surv_probs")

# Goodness-of-fit for standard parametric models
summary(PERSUADE, type = "gof")

# Goodness-of-fit for spline-based models
summary(PERSUADE, type = "gof_spline")

# Goodness-of-fit for cure models
summary(PERSUADE, type = "gof_cure")

5. Visualize results

# Set colour palette for Figures
palette(rainbow(n = 9, s = 1, v = 1, start = 0, end = max(1, 9 - 1)/9, alpha = 1)) 

# Kaplan-Meier curves
plot(PERSUADE, type = "km")

# Proportional hazards diagnostics
plot(PERSUADE, type = "ph")

# Observed smoothed hazard
plot(PERSUADE, type = "hr")

# Standard parametric models
plot(PERSUADE, type = "param_models")

# Spline-based models
plot(PERSUADE, type = "spline_models")

# Cure models
plot(PERSUADE, type = "cure_models")

# Set colour palette to default
palette("default") 

6. Generate the report

f_generate_report(PERSUADE)

7. Export model parameters

# Copy to the Windows clipboard (for the PERSUADE Excel template)
if (.Platform$OS.type == "windows") {
  write.table(PERSUADE$surv_model_excel, "clipboard-128",
              sep = "\t", col.names = FALSE)
}

# Export to CSV (use getwd() instead of tempdir() for persistent files)
output_dir <- file.path(tempdir(), paste0(PERSUADE$name, "_output"))
dir.create(output_dir, recursive = TRUE, showWarnings = FALSE)
write.csv(PERSUADE$surv_model_excel,
          file.path(output_dir,
                    "PERSUADE_Time-to-event_models_parameters_comma.csv"))
write.csv2(PERSUADE$surv_model_excel,
           file.path(output_dir,
                     "PERSUADE_Time-to-event_models_parameters_semicolon.csv"))

8. Obtain Excel template to incorporate model parameters in decision-analytic model

f_get_excel_template()

Workflow diagram

Visualize the process via the included diagram:
PERSUADE Workflow Overview

(Alternatively, open the .vsdx version if preferred.)


Tips for running your own analyses

Start by running the example script to familiarize yourself with the workflow. For your own data:


NSCLC example survival datasets

PERSUADE includes 33 reviewed trial-population datasets of reconstructed pseudo-individual patient data (pseudo-IPD) for overall survival in advanced non-small cell lung cancer (NSCLC), covering EGFR-targeted therapies, ALK-targeted therapies, and immunotherapies. The collection contains 11,572 reconstructed records across 66 treatment arms.

If your installed release does not include these datasets, install the development version shown above.

library(PERSUADE)
data("nsclc_ipd", package = "PERSUADE")
data("nsclc_trials", package = "PERSUADE")

# Discover comparisons and select one by its stable identifier
nsclc_trials[, c("dataset_id", "trial_id", "population")]
example_id <- "EGFR_Lux-Lung3"
example_ipd <- subset(nsclc_ipd, dataset_id == example_id)
example_trial <- subset(nsclc_trials, dataset_id == example_id)
example_trial[, c("population", "intervention_treatment", "control_treatment")]

Estimate and plot Kaplan-Meier survival by treatment arm (times are in months):

km <- survival::survfit(
  survival::Surv(time_months, event) ~ arm,
  data = example_ipd
)
plot(km, col = c("#0072B2", "#D55E00"), lty = 1:2,
     xlab = "Time (months)", ylab = "Overall survival probability")
legend("topright", col = c("#0072B2", "#D55E00"), lty = 1:2, bty = "n",
       legend = example_trial[, c("control_treatment", "intervention_treatment")])

Use dataset_id to find the source publication without relying on row order:

example_trial[, c("trial_publication", "trial_url")]
trial_url <- example_trial$trial_url[1L]
if (interactive() && !is.na(trial_url) && nzchar(trial_url)) {
  utils::browseURL(trial_url)
}

To use this example in the workflow below, supply years = example_ipd$time_months / 12, status = example_ipd$event, and group = example_ipd$arm; keep the prediction horizon and time points in years.

These are reconstructed observations, not original patient records. All 33 datasets were reviewed against published aggregate survival results; see ?nsclc_ipd for known discrepancies. Event fractions describe reconstructed deaths and do not directly measure follow-up maturity or tail precision. Some trial populations overlap and must not be pooled as independent cohorts. When reusing the data, cite the original trial publications, Simons et al. (2020), and Guyot et al. (2012), as listed in the help pages. The digitized source archive is available on Zenodo under CC BY 4.0.


Extending or customizing


Acknowledgments & history


License & contact

Licensed under GPL3.
For questions, enhancements, or collaboration, reach out via GitHub discussions or issues.