evaluate_vignette <- requireNamespace("colorspace", quietly = TRUE)
knitr::opts_chunk$set(eval = evaluate_vignette)library(survival)
library(casebase)
library(ggplot2)
library(data.table)
library(colorspace)
data("ERSPC")
# create poptime object for ERSPC data with exposure attribute
x <- popTime(ERSPC, time = "Follow.Up.Time", event = "DeadOfPrCa", exposure = "ScrArm")
head(x)## ScrArm time event original.time original.event event status ycoord yc
## 1: 0 0.0027 0 0.0027 0 censored 88232 0
## 2: 0 0.0027 0 0.0027 0 censored 88231 0
## 3: 0 0.0027 0 0.0027 0 censored 88230 0
## 4: 0 0.0027 0 0.0027 0 censored 88229 0
## 5: 0 0.0137 0 0.0137 0 censored 88228 0
## 6: 0 0.0137 0 0.0137 0 censored 88227 0
## n_available
## 1: 0
## 2: 0
## 3: 0
## 4: 0
## 5: 0
## 6: 0
In this vignette, we explain in details how to customize population time plots. More specifically, we details the inner workings of the plot method for objects of class popTime.
.params argumentsThe user can have greater control over the aesthetics of a population plot by specifying these in the .params arguments. These need to be specified as lists and are subsequently passed on to the following ggplot2 functions:
ribbon.params –> ggplot2::geom_ribbon()case.params –> ggplot2::geom_point()base.params –> ggplot2::geom_point()competing.params –> ggplot2::geom_point()fill.params –> ggplot2::scale_fill_manual()color.params –> ggplot2::scale_colour_manual()theme.params –> ggplot2::theme()Following the suggestion from the ggplot2 book, we use the utils::modifyList function to replace the corresponding default values. For example, the default arguments passed to the geom_ribbon function for plotting the area are given by
## $data
## ScrArm time event original.time original.event event status ycoord
## 1: 0 0.0027 0 0.0027 0 censored 88232
## 2: 0 0.0027 0 0.0027 0 censored 88231
## 3: 0 0.0027 0 0.0027 0 censored 88230
## 4: 0 0.0027 0 0.0027 0 censored 88229
## 5: 0 0.0137 0 0.0137 0 censored 88228
## ---
## 159889: 1 14.9405 0 14.9405 0 censored 5
## 159890: 1 14.9405 0 14.9405 0 censored 4
## 159891: 1 14.9405 0 14.9405 0 censored 3
## 159892: 1 14.9405 0 14.9405 0 censored 2
## 159893: 1 14.9405 0 14.9405 0 censored 1
## yc n_available
## 1: 0 0
## 2: 0 0
## 3: 0 0
## 4: 0 0
## 5: 0 0
## ---
## 159889: 0 0
## 159890: 0 0
## 159891: 0 0
## 159892: 0 0
## 159893: 0 0
##
## $mapping
## Aesthetic mapping:
## * `x` -> `time`
## * `ymin` -> 0
## * `ymax` -> `ycoord`
##
## $fill
## [1] "grey80"
##
## $alpha
## [1] 0.5
Note that the variables time and ycoord are columns created by the casebase::popTime function, so we should always leave these specified as is. Suppose we want to change the fill color. We simply specify this color in the ribbon.params argument:
We then call the utils::modifyList function to override the function defaults:
(new_ribbon_params <- utils::modifyList(list(data = x,
mapping = aes(x = time, ymin = 0, ymax = ycoord),
fill = "grey80",
alpha = 0.5),
ribbon.params))## $data
## ScrArm time event original.time original.event event status ycoord
## 1: 0 0.0027 0 0.0027 0 censored 88232
## 2: 0 0.0027 0 0.0027 0 censored 88231
## 3: 0 0.0027 0 0.0027 0 censored 88230
## 4: 0 0.0027 0 0.0027 0 censored 88229
## 5: 0 0.0137 0 0.0137 0 censored 88228
## ---
## 159889: 1 14.9405 0 14.9405 0 censored 5
## 159890: 1 14.9405 0 14.9405 0 censored 4
## 159891: 1 14.9405 0 14.9405 0 censored 3
## 159892: 1 14.9405 0 14.9405 0 censored 2
## 159893: 1 14.9405 0 14.9405 0 censored 1
## yc n_available
## 1: 0 0
## 2: 0 0
## 3: 0 0
## 4: 0 0
## 5: 0 0
## ---
## 159889: 0 0
## 159890: 0 0
## 159891: 0 0
## 159892: 0 0
## 159893: 0 0
##
## $mapping
## Aesthetic mapping:
## * `x` -> `time`
## * `ymin` -> 0
## * `ymax` -> `ycoord`
##
## $fill
## [1] "#0072B2"
##
## $alpha
## [1] 0.5
Finally, we use base::do.call to execute the geom_ribbon function on this list:
The default arguments to the facet.params argument is given by:
exposure_variable <- attr(x, "exposure")
default_facet_params <- list(facets = exposure_variable, ncol = 1)The population time area stratified by treatment arm is then plotted using the following code
ggplot() +
base::do.call("geom_ribbon", new_ribbon_params) +
base::do.call("facet_wrap", default_facet_params) We can modify the facet labels by either changing the factor labels in the data or specifying the labeller argument. See this blog post for further details. Here is an example of how we can change the facet labels using the plot method provided by the casebase package:
# Use character vectors as lookup tables:
group_status <- c(
`0` = "Control Arm",
`1` = "Screening Arm"
)
plot(x,
add.case.series = FALSE, # do not plot the case serires
facet.params = list(labeller = labeller(ScrArm = group_status), # change labels
strip.position = "right") # change facet position
) Suppose we want to change the color of the points and the legend labels. We use the bmtcrr dataset as the example in this section.
The reason there are both fill.params and color.params arguments, is because by default, we use shape = 21 which is a filled circle (see the pch argument of the graphics::points function for details). Shapes from 21 to 25 can be colored and filled with different colors: color.params gives the border color and fill.params gives the fill color (sometimes referred to as the background color).
The default fill colors for the case series, base series and competing event are given by the qualitative palette from the colorspace R package:
fill_cols <- colorspace::qualitative_hcl(n = 3, palette = "Dark3")
(fill_colors <- c("Case series" = fill_cols[1],
"Competing event" = fill_cols[3],
"Base series" = fill_cols[2]))## Case series Competing event Base series
## "#E16A86" "#009ADE" "#50A315"
The corresponding default border colors are given by the colorspace::darken function applied to the fill colors above:
color_cols <- colorspace::darken(col = fill_cols, amount = 0.3)
(color_colors <- c("Case series" = color_cols[1],
"Competing event" = color_cols[3],
"Base series" = color_cols[2]))## Case series Competing event Base series
## "#AB3A59" "#026A9A" "#347004"
This is what the points look like:
If you only want to change the color points, you must specify a named vector exactly as specified in the fill_colors object created above. Note that the names Case series, Base Series and Competing event must remain the same, otherwise the function won’t know how to map the colors to the corresponding points. This is because the colour and fill aesthetic mappings in the geom_point functions have been set to Case series, Base Series and Competing event. For example, the default call to geom_point for the case series is given by:
ggplot() + do.call("geom_point", list(data = x[event == 1],
mapping = aes(x = time, y = yc,
colour = "Case series", fill = "Case series"),
size = 1.5,
alpha = 0.5,
shape = 21))We define a new set of colors using a sequential (multi-hue) palette:
fill_cols <- colorspace::sequential_hcl(n = 3, palette = "Viridis")
(fill_colors <- c("Case series" = fill_cols[1],
"Competing event" = fill_cols[3],
"Base series" = fill_cols[2]))## Case series Competing event Base series
## "#4B0055" "#FDE333" "#009B95"
color_cols <- colorspace::darken(col = fill_cols, amount = 0.3)
(color_colors <- c("Case series" = color_cols[1],
"Competing event" = color_cols[3],
"Base series" = color_cols[2]))## Case series Competing event Base series
## "#3A0142" "#AC9900" "#0A6B66"
We then pass fill_cols and color_cols to the fill.params and color.params arguments, respectively. Internally, this gets passed to the ggplot2::scale_fill_manual and ggplot2::scale_color_manual functions, respectively:
do.call("scale_fill_manual", utils::modifyList(
list(name = element_blank(),
breaks = c("Case series", "Competing event", "Base series"),
values = old_cols), list(values = fill_colors))
)
do.call("scale_colour_manual", utils::modifyList(
list(name = element_blank(),
breaks = c("Case series", "Competing event", "Base series"),
values = old_cols), list(values = color_colors))
)Here is the code to only change the colors:
# this data ships with the casebase package
data("bmtcrr")
popTimeData <- popTime(data = bmtcrr, time = "ftime", exposure = "D")## 'Status' will be used as the event variable
plot(popTimeData,
add.case.series = TRUE,
add.base.series = TRUE,
add.competing.event = TRUE,
comprisk = TRUE,
fill.params = list(values = fill_colors),
color.params = list(value = color_colors))Note that if you only specify one of the fill.params or color.params arguments, the plot method will automatically set one equal to the other and return a warning message:
plot(popTimeData,
add.case.series = TRUE,
add.base.series = TRUE,
add.competing.event = TRUE,
ratio = 1,
comprisk = TRUE,
legend = TRUE,
fill.params = list(values = fill_colors))## Warning in plot.popTime(popTimeData, add.case.series = TRUE, add.base.series
## = TRUE, : fill.params has been specified by the user but color.params has not.
## Setting color.params to be equal to fill.params.
In order to change both the point colors and legend labels, we must modify the aesthetic mapping of the geom_point calls as follows:
# this data ships with the casebase package
data("bmtcrr")
popTimeData <- popTime(data = bmtcrr, time = "ftime", exposure = "D")## 'Status' will be used as the event variable
plot(popTimeData,
add.case.series = TRUE,
add.base.series = TRUE,
add.competing.event = TRUE,
comprisk = TRUE,
case.params = list(mapping = aes(x = time, y = yc, fill = "Relapse", colour = "Relapse")),
base.params = list(mapping = aes(x = time, y = ycoord, fill = "Base series", colour = "Base series")),
competing.params = list(mapping = aes(x = time, y = yc, fill = "Competing event", colour = "Competing event")),
fill.params = list(name = "Legend Name",
breaks = c("Relapse", "Base series", "Competing event"),
values = c("Relapse" = "blue", "Competing event" = "hotpink", "Base series" = "orange")))## Warning in plot.popTime(popTimeData, add.case.series = TRUE, add.base.series
## = TRUE, : fill.params has been specified by the user but color.params has not.
## Setting color.params to be equal to fill.params.
NOTE: the lists being passed to the .params arguments must be named arguments, otherwise they will give unexpected behavior. For example
## R version 4.0.2 (2020-06-22)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS 10.16
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] colorspace_2.0-0 data.table_1.13.2 ggplot2_3.3.2 survival_3.2-7
## [5] casebase_0.9.1
##
## loaded via a namespace (and not attached):
## [1] pillar_1.4.7 compiler_4.0.2 highr_0.8 tools_4.0.2
## [5] digest_0.6.27 evaluate_0.14 lifecycle_0.2.0 tibble_3.0.6
## [9] gtable_0.3.0 nlme_3.1-150 lattice_0.20-41 mgcv_1.8-33
## [13] pkgconfig_2.0.3 rlang_0.4.10 Matrix_1.2-18 yaml_2.2.1
## [17] xfun_0.20 withr_2.4.1 stringr_1.4.0 dplyr_1.0.2
## [21] knitr_1.31 generics_0.1.0 vctrs_0.3.6 stats4_4.0.2
## [25] grid_4.0.2 tidyselect_1.1.0 glue_1.4.2 R6_2.5.0
## [29] VGAM_1.1-4 rmarkdown_2.6 farver_2.0.3 purrr_0.3.4
## [33] magrittr_2.0.1 scales_1.1.1 ellipsis_0.3.1 htmltools_0.5.0
## [37] splines_4.0.2 labeling_0.4.2 stringi_1.5.3 munsell_0.5.0
## [41] crayon_1.4.0