vignettes/customizingpopTime.Rmd
customizingpopTime.Rmd
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
## <fctr> <num> <num> <num> <int> <fctr> <int>
## 1: Control group 0.0027 0 0.0027 0 censored 88232
## 2: Control group 0.0027 0 0.0027 0 censored 88231
## 3: Control group 0.0027 0 0.0027 0 censored 88230
## 4: Control group 0.0027 0 0.0027 0 censored 88229
## 5: Control group 0.0137 0 0.0137 0 censored 88228
## 6: Control group 0.0137 0 0.0137 0 censored 88227
## yc n_available
## <int> <int>
## 1: 0 0
## 2: 0 0
## 3: 0 0
## 4: 0 0
## 5: 0 0
## 6: 0 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
arguments
The 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
## <fctr> <num> <num> <num> <int> <fctr>
## 1: Control group 0.0027 0 0.0027 0 censored
## 2: Control group 0.0027 0 0.0027 0 censored
## 3: Control group 0.0027 0 0.0027 0 censored
## 4: Control group 0.0027 0 0.0027 0 censored
## 5: Control group 0.0137 0 0.0137 0 censored
## ---
## 159889: Screening group 14.9405 0 14.9405 0 censored
## 159890: Screening group 14.9405 0 14.9405 0 censored
## 159891: Screening group 14.9405 0 14.9405 0 censored
## 159892: Screening group 14.9405 0 14.9405 0 censored
## 159893: Screening group 14.9405 0 14.9405 0 censored
## ycoord yc n_available
## <int> <int> <int>
## 1: 88232 0 0
## 2: 88231 0 0
## 3: 88230 0 0
## 4: 88229 0 0
## 5: 88228 0 0
## ---
## 159889: 5 0 0
## 159890: 4 0 0
## 159891: 3 0 0
## 159892: 2 0 0
## 159893: 1 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:
ribbon.params <- list(fill = "#0072B2")
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
## <fctr> <num> <num> <num> <int> <fctr>
## 1: Control group 0.0027 0 0.0027 0 censored
## 2: Control group 0.0027 0 0.0027 0 censored
## 3: Control group 0.0027 0 0.0027 0 censored
## 4: Control group 0.0027 0 0.0027 0 censored
## 5: Control group 0.0137 0 0.0137 0 censored
## ---
## 159889: Screening group 14.9405 0 14.9405 0 censored
## 159890: Screening group 14.9405 0 14.9405 0 censored
## 159891: Screening group 14.9405 0 14.9405 0 censored
## 159892: Screening group 14.9405 0 14.9405 0 censored
## 159893: Screening group 14.9405 0 14.9405 0 censored
## ycoord yc n_available
## <int> <int> <int>
## 1: 88232 0 0
## 2: 88231 0 0
## 3: 88230 0 0
## 4: 88229 0 0
## 5: 88228 0 0
## ---
## 159889: 5 0 0
## 159890: 4 0 0
## 159891: 3 0 0
## 159892: 2 0 0
## 159893: 1 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)
# this is equivalent to
# plot(x, add.case.series = FALSE)
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
)
## Warning: No shared levels found between `names(values)` of the manual scale and the
## data's colour values.
## Warning: No shared levels found between `names(values)` of the manual scale and the
## data's fill values.
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.4.1 (2024-06-14)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 22.04.4 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so; LAPACK version 3.10.0
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] colorspace_2.1-1 data.table_1.15.4 ggplot2_3.5.1 casebase_0.10.6
## [5] survival_3.6-4
##
## loaded via a namespace (and not attached):
## [1] Matrix_1.7-0 gtable_0.3.5 jsonlite_1.8.8 highr_0.11
## [5] dplyr_1.1.4 compiler_4.4.1 tidyselect_1.2.1 VGAM_1.1-11
## [9] jquerylib_0.1.4 splines_4.4.1 systemfonts_1.1.0 scales_1.3.0
## [13] textshaping_0.4.0 yaml_2.3.10 fastmap_1.2.0 lattice_0.22-6
## [17] R6_2.5.1 labeling_0.4.3 generics_0.1.3 knitr_1.48
## [21] tibble_3.2.1 desc_1.4.3 munsell_0.5.1 bslib_0.8.0
## [25] pillar_1.9.0 rlang_1.1.4 utf8_1.2.4 cachem_1.1.0
## [29] xfun_0.46 fs_1.6.4 sass_0.4.9 cli_3.6.3
## [33] withr_3.0.1 mgcv_1.9-1 pkgdown_2.1.0 magrittr_2.0.3
## [37] digest_0.6.36 grid_4.4.1 nlme_3.1-164 lifecycle_1.0.4
## [41] vctrs_0.6.5 evaluate_0.24.0 glue_1.7.0 farver_2.1.2
## [45] ragg_1.3.2 stats4_4.4.1 fansi_1.0.6 rmarkdown_2.27
## [49] pkgconfig_2.0.3 tools_4.4.1 htmltools_0.5.8.1