Kaplan-Meier Curves in R

In medical research, epidemiology, and reliability engineering, we often need to evaluate the time required for an event (such as patient death or equipment failure) to occur. This statistical approach is known as survival analysis, and the most classic and intuitive visualization tool within it is the Kaplan-Meier curve. This curve clearly illustrates the trend of "survival" probability changes over time across different groups or individuals, making it an indispensable part of the R language's data analysis libraries.

The Kaplan-Meier estimator (abbreviated as KM method) is a non-parametric statistical method that does not rely on specific distribution assumptions about the population but instead estimates the survival function $S(t)$ based on observed data points. Its core logic lies in calculating the proportion of subjects in the sample who have not yet experienced the event (i.e., are still alive or have not failed) at any arbitrary time point $t$. As new events occur, this proportion decreases accordingly, forming a step-like curve. This stepped characteristic allows the KM curve to precisely reflect the censoring situations present in the data, referring to individuals who have not yet experienced the event by the end of the study.
To plot Kaplan-Meier curves, it is first necessary to ensure that your R environment has the required packages installed. While basic plotting capabilities may depend on ggplot2, the survival package specifically designed for survival analysis offers the most standard and robust implementation.

You can use the following commands to install and load the necessary libraries:

# Install survminer and survival packages (if not already installed)
install.packages(c("survival", "survminer"))

# Load libraries
library(survival)
library(ggplot2)

The survival package provides the core Surv() function to construct survival objects, as well as the survfit() function to calculate estimates of survival probabilities. The survminer package, on the other hand, encapsulates these functionalities and provides a more aesthetically pleasing plotting interface, particularly for drawing KM curves that include confidence intervals.

Data Preparation and Survival Object Construction

In practical operations, we typically possess a dataset containing time variables and status variables. For instance, in medical research, there might be one column recording the follow-up time for patients (Time), and another column indicating whether a death event occurred for that patient (Status, typically 0 for survival and 1 for death).

Assume we have a dataset named lung containing two columns: time (survival time) and status (survival status). In R, we need to combine these two columns into a single survival object. The first argument of the Surv() function is the time, and the second argument is the event indicator.

# Create survival object
surv_obj <- Surv(time = lung$time, event = lung$status)

This step is crucial, as it converts raw data into a format understandable by statistical models, explicitly distinguishing between "observed time" and "whether the target event occurred". If the data contains censoring (e.g., patients removed from the study midway or still alive at the end of the study), the Surv() function automatically incorporates these scenarios into its calculation logic.

Calculating Survival Probabilities and Confidence Intervals with survfit

Once a survival object is constructed, the next step is to use the survfit() function to calculate specific estimates of survival probabilities along with their confidence intervals. This function can accept a single survival object or a list of survival objects containing multiple groups.

If we wish to compare the survival status of patients across different sexes (sex), we can group the data by sex:

# Calculate survival fit results, grouped by sex
km_fit <- survfit(surv_obj ~ sex, data = lung)

The survfit() function returns an object containing multiple columns, with the two most important being surv (survival probability) and conf.int (the upper and lower limits of the confidence interval). These numerical values provide a solid foundation for subsequent plotting.

Plotting Kaplan-Meier Curves

With the calculated survival fit results, we can use the ggsurvplot() function to generate professional graphics. This function automatically handles axis labels, legends, and the display of confidence intervals, greatly simplifying the plotting process.

When calling this function, we pass the previously calculated km_fit object as the data source and specify the grouping variable (e.g., strata). To enhance readability, font sizes can be set, and a title for the survival curves can be added.

# Plot Kaplan-Meier curves
p <- ggsurvplot(
  km_fit, 
  data = lung, 
  pval = TRUE,      # Display P values for differences between groups
  conf.int = TRUE,  # Display confidence intervals
  risk.table = TRUE,# Display risk table (cumulative number of events)
  ggtheme = theme_bw(),
  surv.median.line = "hv" # Mark median survival time
)

print(p)

The generated graph will display multiple step-like curves, with each line representing a group. If there are significant differences between groups, the P value will be displayed in the legend; simultaneously, the shaded areas of the curves represent the 95% confidence intervals. Generally, if the area under a specific curve is larger, it usually implies that the survival time for that group is longer or the risk is lower.

Advanced Applications: Log-Rank Test and Visualization Enhancement

In addition to basic plotting, Kaplan-Meier analysis is often accompanied by the Log-Rank test to determine whether there are statistically significant differences in survival curves between different groups. The survminer package can directly integrate this test result into the graphics.

Furthermore, to more intuitively display data distribution, we can overlay a Kernel Density Plot on top of the KM curve to show the density distribution of event occurrence times. This helps identify which time period most events are concentrated within.

# Add density plot based on KM curve
p <- ggsurvplot(
  km_fit, 
  data = lung, 
  funnellab = FALSE, # Hide funnel labels
  risk.table = TRUE,
  ggtheme = theme_minimal(),
  surv.median.line = "hv",
  conf.int = TRUE,
  pval = TRUE,
  layers = c("surv", "density") # Display both survival curve and density plot simultaneously
)

print(p)

Through this method, we can not only see "who lives longer" but also observe "when most people pass away." This multi-dimensional visualization greatly enhances the persuasiveness of the conclusions.

Summary and Best Practices

The Kaplan-Meier curve is a core tool in R for handling survival data. Mastering the three key functions Surv, survfit, and ggsurvplot allows you to efficiently complete the entire process from data processing to result visualization. In practical applications, it is essential to pay attention to data cleaning, ensuring that time variables are positive and status variables are logically correct (typically 0/1 or 2/1). Additionally, reasonably setting parameters for confidence intervals and risk tables will make your analytical reports more rigorous and professional. Whether writing academic papers or conducting business reports, the powerful survival analysis capabilities provided by R can prove invaluable.