---
title: "Creating survival plot"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Creating survival plot}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  echo = TRUE,
  eval = TRUE,
  fig.height = 6,
  fig.width = 9,
  fig.align='center'
)
```

After inserting the `survfit{survival}` object into `surv.plot{survSAKK}`, we can create simple survival curves, allowing to visualize survival patterns and incorporate various statistics in our plot.

To show some benefit of this function,  *NCCTG Lung Cancer Data*, available in the survival package is used.

# Setup and Loading Data

```{r setup, warning=FALSE}

# Load required libraries
library(survSAKK)
library(survival)

# Load lung data
lung <- survival::lung

# Compute survival time in months and years
lung$time.m <- lung$time/365.25*12
lung$time.y <- lung$time/365.25

# Create survival objects
fit.lung.d <- survfit(Surv(time, status) ~ 1, data = lung)
fit.lung.m <- survfit(Surv(time.m, status) ~ 1, data = lung)
fit.lung.arm.m <- survfit(Surv(time.m, status) ~ sex, data = lung)
fit.lung.arm.y <- survfit(Surv(time.y, status) ~ sex, data = lung)

```

# Drawing basic survival plot

```{r baseplot1}
# Single arm
surv.plot(fit.lung.m)

# Two arm
surv.plot(fit.lung.arm.m)
```

# Customisation of the survival plot

## Colour, title and axis label

```{r baseplot2}
surv.plot(fit.lung.arm.m,
          # Colour
          col = c("cadetblue2", "cadetblue"),
          # Title
          main = "Kaplan-Meier plot",
          # Axis label
          xlab = "Time since treatment start (months)",
          ylab = "Overall survival (probability)"
)
```


## Legend position, name and title

```{r baseplot3}
# Choose legend position and names of the arms
surv.plot(fit.lung.arm.m,
          legend.position = "bottomleft",
          legend.name = c("Male", "Female")
)

# Choose legend position manually and add a legend title
surv.plot(fit.lung.arm.m,
          legend.position = c(18, 0.9),
          legend.name = c("Male", "Female"),
          legend.title = "Sex"
)
```

## Axis limits, xticks and yticks

```{r baseplot4}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          xticks = seq(0, 36, by = 12), 
          yticks = seq(0, 1, by = 0.2)
)
# Cut curve at 24 months
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          xticks = seq(0, 24, by = 6)
)
```


## Font size

### Global adjustment

```{r baseplot6}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          # Global adjustment
          cex = 1.3,
          risktable.name.position = -6,
          risktable.title.position = -6
)
```


### Specific adjustment

```{r baseplot7}
surv.plot(fit.lung.arm.m,
          main = "Kaplan-Meier plot",
          legend.name = c("Male", "Female"),
          legend.title = "Sex",
          # Size of x-axis label
          xlab.cex = 1.2,
          # Size of y-axis label
          ylab.cex = 1.2,
          # Size of axis elements
          axis.cex = 0.8,
          # Size of the censoirng marks
          censoring.cex = 1,
          # Size of the legend title
          legend.title.cex = 1.2,
          # Size of the risktable
          risktable.cex = 0.7,
          # Size of the risktable name
          risktable.name.cex = 0.9
)
```


## Label position x and y axis

### Shift x and y axis label

```{r baseplot8}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          xlab.pos = 6,
          ylab.pos = 5
)
```


## Margin area customisation

```{r baseplot9}

# Change the margins and shift the y axis label
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          # New margin area 
          margin.bottom = 6,
          margin.left = 7,
          margin.top = 1,
          margin.right = 2,
          # Define margin of the y-axis label
          ylab.pos = 4
)
```


## Time unit and y-axis unit

The parameter `time.unit` can be set as follows: `"day"`, `"week"`, `"month"`,`"year"`.
 
**Note the following:** 

- The time unit in `time.unit` needs to correspond to the time unit which was used to calculate the survival object `fit`.

- If `time.unit = "month"` x ticks are automatically chosen by intervals of 6 months. Whereas for `time.unit = "year"` the x ticks are chosen by intervals of 1. 

```{r baseplot10}
# Time unit of month
surv.plot(fit.lung.arm.m,
          time.unit = "month",
          y.unit = "probability",
          legend.name = c("Male", "Female")
)

# Time unit of year
surv.plot(fit.lung.arm.y,
          time.unit = "year",
          y.unit = "percent",
          legend.name = c("Male", "Female")
)
```

# Drawing risk table

Per default the risk table is provided below the Kaplan-Meier plot. It provides information about the number of patients at risk at different time points.

## Undisplay risk table

```{r risktable1}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          risktable = FALSE
)
```

## Risktable position

```{r risktable.pos1}
# Move risk table names and titles to the left
surv.plot(fit.lung.arm.m,
          legend.name = c("male", "female"),
          risktable.name.position = -6,
          risktable.title.position = -6
)
```

## Risktable title, colour and label name

```{r risktable.pos2}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          risktable.name = c("M", "F"),
          risktable.col = TRUE,
          risktable.title = "Number at risk",
          risktable.title.font = 4,
          risktable.title.col = "#E41A1C"
)
```

## Risktable with censoring indication 

```{r risktable_censoring}
surv.plot(fit.lung.arm.m,
          risktable.censoring = TRUE)
```


# Drawing segment

This section explains how to highlight a **specific quantile** or
**time point** as a segment in the survival curve and how to adjust segment annotation.

## For a specific quantile


```{r median}
# Drawing a segment line for the median, which corresponds to 0.5 quantile
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          segment.quantile = 0.5
)

surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          segment.quantile = 0.5,
          # Specifying time unit
          time.unit = "month"
)
```


```{r quantile0_75}
# Drawing segment for the 0.75 quantile
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          segment.quantile = 0.75
)
```

## For a specific time point


```{r timepoint}
#  Drawing a segment line at 12 months
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          time.unit = "month",
          segment.timepoint = 12
)
```

# Customisation of the segment

## Change position of segment annotation

The parameter `segment.annotation` can take the following values: `c(x,y)`,`"bottomleft"`, `"left"`, `"right"`, `"top"`, `"none"`

```{r segment1}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          segment.timepoint = 18,
          segment.annotation = "top",
          time.unit = "month"
)
```


## Segment title, font, size, and colour

```{r segment2}
surv.plot(fit.lung.arm.m,
          col = c("cadetblue2", "cadetblue"),
          legend.name = c("Male", "Female"),
          time.unit = "month",
          segment.quantile = 0.5,
          segment.font = 10,
          segment.main.font = 11,
          segment.main = "Median PFS in months (95% CI)",
          segment.cex = 0.8,
          segment.annotation.col = "darkgray"
)
```


## Segment lines for different time points / quantile

Note that `segment.annotation` needs to be set to "none". Otherwise the code does not work. 

```{r segment3}
# Several quantiles
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          segment.quantile = c(0.5, 0.25),
          segment.annotation = "none",
          time.unit = "month"
)

# Several time points
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          segment.timepoint = c(6, 18),
          segment.annotation = "none",
          time.unit = "month"
)
```

## Segment line type, line width and text spacing

```{r segment5}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          time.unit = "month",
          segment.quantile = 0.5,
          segment.lwd = 2,
          segment.lty = "dashed",
          segment.annotation.space = 0.1
)
```

## Segment annotation short version 

Note that the option `segment.confint = FALSE` only works for two arms. 

```{r segment7}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          time.unit = "month",
          segment.quantile = 0.5,
          segment.confint = FALSE
)
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          time.unit = "month",
          segment.timepoint = 18,
          segment.confint = FALSE,
          segment.annotation = "bottomleft"
)
```

# Modify confidence interval 

```{r segment6}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          segment.quantile = 0.5,
          conf.int = 0.8
)

surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          time.unit = "month",
          segment.timepoint = 18,
          y.unit = "percent",
          conf.int = 0.9
)
```

# Include statistics

There are three options for the parameter `stat` to display statistics:

- `logrank`: gives the p value of the log rank test calculated using `survdiff{survival}`.

- `coxph`: gives the hazard ratio (HR) and its 95% CI of the conducted Cox proportional hazards regression using `coxph{survival}`.⁠

- `coxph_logrank`: is a combination of `logrank` and `coxph`.

## `logrank test`

```{r stat1}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          stat = "logrank",
)
```

## `coxph`

```{r stat2}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          stat = "coxph"
)
```

## `coxph_logrank`

```{r stat3}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          stat = "coxph_logrank"
)
```


# Customisation of the statistics

## Stat position, colour, text size, and text font

```{r stat4}
surv.plot(fit.lung.arm.m,
          legend.name = c("Male", "Female"),
          stat = "logrank",
          stat.position = "right",
          stat.col = "darkgrey",
          stat.cex = 0.8,
          stat.font = 3
)
```


## Stat with redfined reference arm and confidence level

```{r stat_ref_arm}
surv.plot(fit.lung.arm.m,
          legend.name = c("Female","Male"),
          stat = "coxph_logrank",
          reference.arm = 2,
          stat.conf.int = 0.80
)
```

## Stat with stratification

In the next example the ECOG performance status is used as stratification factor for the calculation of the statistics. 

```{r stat_stratified}
# Fit survival object with stratification

fit_lung_stratified <- survfit(Surv(time.m, status) ~ sex + strata(ph.ecog), data = lung)

surv.plot(fit.lung.arm.m,
          stat.fit = fit_lung_stratified,
          legend.name = c("Male", "Female"),
          stat = "coxph_logrank"
)
```


# Predefined theme options

The following themes are implemented: `SAKK`, `Lancet`, `JCO`, `WCLC`, `ESMO`

```{r Design1}

surv.plot(fit.lung.arm.m,
          theme = "ESMO")

```

```{r Design2}

surv.plot(fit.lung.arm.m,
          theme = "Lancet")

```


# Multiple survival plots

We present to ways how to combine plots: via `par(mfrow=c())` and via `split.screen()`

## Multiple plots using `par(mfrow=c())` 

```{r default_setting, echo=FALSE, eval=TRUE}
# Save old settings
users_default_setting <- par(no.readonly = TRUE) 
```

```{r plots1, fig.height = 8, fig.width = 8}
# Creating 4 sub-plot
par(mfrow=c(2,2))

# Plot 1
surv.plot(fit.lung.d)
# Plot 2
surv.plot(fit.lung.arm.m, 
          time.unit = "month")
# Plot 3
surv.plot(fit.lung.arm.y, 
          col = c("cadetblue2", "cadetblue"), 
          time.unit = "year", 
          stat = "coxph")
# Plot 4
surv.plot(fit.lung.arm.m,
          # Cusomization of the survival plot
          main = "Kaplan-Meier plot",
          legend.name = c("Male", "Female"),
          legend.title = "Sex",
          xlab.cex = 1.2,
          ylab.cex = 1.2,
          axis.cex = 0.8,
          censoring.cex = 1,
          legend.title.cex = 1.2,
          # Customization of the risktable
          risktable.name.position = -9,
          risktable.title.position = -9,
          risktable.cex = 0.7)
```

```{r plots2, fig.height = 10, fig.width = 8}
par(mfrow=c(2,1))
# Plot 1
surv.plot(fit.lung.arm.m, 
          col = c("cadetblue2", "cadetblue"), 
          time.unit = "month", 
          segment.quantile = 0.5)
# Plot 2
surv.plot(fit.lung.arm.m, 
          col = c("cadetblue2", "cadetblue"), 
          time.unit = "month", 
          segment.timepoint = 6)
```

```{r resetSetting, echo = FALSE, eval = TRUE}
# Ensure that old settings are restored when the function exits
par(users_default_setting)
```

## Multiple plots using `split.screen()` 

```{r plots3, fig.height = 10, fig.width = 8}
split.screen(c(2,1))
screen(1)
surv.plot(fit.lung.arm.m, 
          time.unit = "month", 
          segment.quantile = 0.5, 
          segment.confint = FALSE)
screen(2)
surv.plot(fit.lung.arm.m, 
          time.unit = "month", 
          segment.quantile = 0.75, 
          segment.confint = FALSE)
close.screen(all = TRUE)
```

# Export plots as png file

## Figure output for a report

The following examples show how a figure can be exported as png file for a report. 

```{r export1, eval = FALSE}

png(file = file.path("kaplan_meier_plot.png"),
    width = 20,
    height = 14,
    units = "cm",
    res = 300)
surv.plot(fit.lung.arm.m,
          risktable.name.position=-4,
          risktable.title.position=-4)
dev.off()
```

## Figure output for a poster

If a bigger font size is needed then this can be done efficiently by choosing a different size of the output file. 

```{r export2, eval = FALSE}

png(file = file.path("kaplan_meier_plot_big_font.png"),
    width = 20*0.7,
    height = 14*0.7,
    units = "cm",
    res = 300)
surv.plot(fit.lung.arm.m,
          ylab = "Estimated survival \n (probability)",
          risktable.name.position=-6.5,
          risktable.title.position=-6.5)
dev.off()
```