---
title: "survParamSim"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{survParamSim}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
```{r setup}
library(dplyr)
library(ggplot2)
library(survival)
library(survParamSim)
set.seed(12345)
```
The goal of survParamSim is to perform survival simulation with parametric survival model generated from 'survreg' function in 'survival' package.
In each simulation, coefficients are resampled from variance-covariance matrix of parameter estimates, in order to capture uncertainty in model parameters.
## Fit model with `survreg()` function
Before running a parametric survival simulation, you need to fit a model to your data using `survreg()` function of `survival` package.
In this vignette, we will be using `colon` dataset available in `survival` package, where the treatment effect of adjuvant Levamisole+5-FU for colon cancer over placebo is evaluated.
First, we load the data and do some data wrangling.
```{r prep}
# ref for dataset https://vincentarelbundock.github.io/Rdatasets/doc/survival/colon.html
colon2 <-
as_tibble(colon) %>%
# recurrence only and not including Lev alone arm
filter(rx != "Lev",
etype == 1) %>%
# Same definition as Lin et al, 1994
mutate(rx = factor(rx, levels = c("Obs", "Lev+5FU")),
depth = as.numeric(extent <= 2))
```
Shown below are Kaplan-Meier curves for visually checking the data.
The second plot is looking at how many censoring we have over time.
Looks like we have a fairly uniform censoring between 1800 to 3000 days - this is attributable to a steady clinical study enrollment.
```{r plot_raw_data}
survfit.colon <- survfit(Surv(time, status) ~ rx, data = colon2)
survminer::ggsurvplot(survfit.colon)
survfit.colon.censor <- survfit(Surv(time, 1-status) ~ rx, data = colon2)
survminer::ggsurvplot(survfit.colon.censor)
```
Next we fit a lognormal parametric model for the data.
Here we are using `node4` and `depth` as additional covariates in addition to treatment (`rx`).
You can see that all of the factor has strong association with the outcome.
```{r fit}
fit.colon <- survreg(Surv(time, status) ~ rx + node4 + depth,
data = colon2, dist = "lognormal")
summary(fit.colon)
```
## Perform simulation
`surv_param_sim()` is the main function of the package that takes `survreg` object as described above.
It also require you to supply `newdata`, which is required even if it is not new - i.e. the same data was used for both `survreg()` and `surv_param_sim()`.
What it does is:
1. Re-sample all the coefficients in the parametric survival model from variance-covariance matrix for `n.rep` times.
2. Perform survival time for all subjects in `newdata` with the corresponding covariates, using one of the resampled coefficients. Also generate censoring time according to `censor.dur` (if not NULL), and replace the simulated survival time above if censoring time is earlier.
4. Repeat the steps 2. for `n.rep` times.
```{r sim}
sim <-
surv_param_sim(object = fit.colon, newdata = colon2,
# Simulate censoring according to the plot above
censor.dur = c(1800, 3000),
# Simulate only 100 times to make the example go fast
n.rep = 100)
```
After the simulation is performed, you can either extract raw simulation results or further calculate Kaplan-Meier estimates or hazard ratio of treatment effect, as you see when you type `sim` in the console.
```{r simout}
sim
```
## Survival time profile
To calculate survival curves for each simulated dataset, `calc_ave_km_pi()` or
`calc_km_pi()` can be used on the simulated object above.
```{r km_pi_calc}
km.pi <- calc_km_pi(sim, trt = "rx")
km.pi
```
Similar to the raw simulated object, you can have a few options for further
processing - one of them is plotting prediction intervals with `plot_km_pi()` function.
```{r km_pi_plot}
plot_km_pi(km.pi) +
theme(legend.position = "bottom") +
labs(y = "Recurrence free rate") +
expand_limits(y = 0)
```
Or providing median survival summary table with `extract_medsurv_pi()` function.
This functionality is only available for `calc_km_pi()` output and has not been
implemented for `calc_ave_km_pi()` yet..
```{r km_pi_table}
extract_medsurv_pi(km.pi)
```
Plot can also be made for subgroups.
You can see that prediction interval is wide for (depth: 1 & nodes4: 1) group, mainly due to small number of subjects
```{r km_pi_group}
km.pi <- calc_km_pi(sim, trt = "rx", group = c("node4", "depth"))
plot_km_pi(km.pi) +
theme(legend.position = "bottom") +
labs(y = "Recurrence free rate") +
expand_limits(y = 0)
```
## Hazard ratios (HRs)
To calculate prediction intervals of HRs, `calc_ave_hr_pi()` or `calc_hr_pi()` can
be used on the simulated object above.
Here I only generated subgroups based on "depth", since the very small N in (depth: 1 & nodes4: 1) can cause issue with calculating HRs.
```{r hr_pi}
hr.pi <- calc_hr_pi(sim, trt = "rx", group = c("depth"))
hr.pi
plot_hr_pi(hr.pi)
```
You can also extract prediction intervals and observed HR with `extract_hr_pi()` function.
```{r hr_pi_table}
extract_hr_pi(hr.pi)
```