## Introduction

The {ggsurvfit} package eases the creation of time-to-event (aka survival) endpoint figures with ggplot. The concise and modular code creates images that are ready for publication or sharing.

## Why ggsurvfit?

Raw variable names do not appear in the figure legend, e.g.

`"sex=Female"`

.You can modify the x-axis scales and the risk table will still align with the plot.

Each add-on function (e.g.

`add_confidence_interval()`

, etc.) is written as a proper ggplot2 ‘geom’, meaning that the package functions can be woven with ggplot2 functions seamlessly.

## Installation

You can install the development version of ggsurvfit from GitHub with:

```
# install.packages("devtools")
devtools::install_github("ddsjoberg/ggsurvfit")
```

## Examples

Let’s begin with an example illustrating a common Kaplan-Meier survival curve.

It’s recommended to use the `survfit2()`

function with this package, rather than `survival::survfit()`

to ensure all quantities are able to be calculated from any environment the functions are called.

```
library(ggsurvfit)
library(ggplot2)
p <-
survfit2(Surv(time, status) ~ sex, data = df_lung) |>
ggsurvfit(size = 1) +
add_censor_mark() +
add_confidence_interval() +
add_risktable() +
add_quantile(color = "gray40", size = 1)
p
```

Because each of the functions are written as proper ggplot geoms, you can add any ggplot function to modify the figure.

```
p +
labs(
y = "Probability of survival",
x = "Months since treatment",
title = "Kaplan-Meier Estimate of Survival by Sex",
# remove the fill and color legend labels (Sex appears in title)
fill = NULL, color = NULL
) +
# reduce padding on edges of figure, and format axes
scale_y_continuous(label = scales::percent, expand = c(0.01, 0)) +
scale_x_continuous(breaks = 0:5*6, expand = c(0.02, 0))
```

The package also supports unstratified models and you can add multiple quantile guidelines.

```
survfit2(Surv(time, status) ~ 1, data = df_lung) |>
ggsurvfit(size = 1) +
add_quantile(linetype = 3, size = 1) +
add_quantile(y_value = 0.25, linetype = 2, size = 1) +
add_confidence_interval() +
add_risktable()
```

You can even facet…but you *cannot* facet with the risktable, however.

```
survfit2(Surv(time, status) ~ sex, data = df_lung) |>
ggsurvfit(size = 1) +
add_censor_mark(shape = 4) +
add_quantile(linetype = 3, size = 1) +
add_confidence_interval() +
ggplot2::facet_grid(~strata)
```

The package works seamlessly with other ggplot extension package, such as {gghighlight}.

```
survfit2(Surv(time, status) ~ ph.ecog, data = df_lung) |>
ggsurvfit(size = 1) +
ggplot2::labs(color = "Gender") +
gghighlight::gghighlight(strata == "Asymptomatic", calculate_per_facet = TRUE)
```

The package also plots cumulative incidence estimates in the presence of competing events.

```
library(tidycmprsk)
cuminc(Surv(ttdeath, death_cr) ~ trt, trial) %>%
ggcuminc(outcome = "death from cancer", size = 1) +
add_confidence_interval() +
add_quantile(y_value = 0.20, size = 1) +
add_risktable() +
labs(x = "Months Since Treatment") +
theme(legend.position = "bottom") +
scale_y_continuous(label = scales::percent, expand = c(0.02, 0)) +
scale_x_continuous(breaks = 0:4 * 6, expand = c(0.02, 0))
```