Time series and line graphs
In this chapter, we will focus on time series graphs, which depict changes in a variable over time. We will also deal with survival (c.q. Kaplan-Meier) graphs and ROC curves.
Line graph
The dataset provided features the mean, standard deviation and sample size at each timepoint.
library(ggplot2)
library(readxl)
library(DescTools)
line_data <- read_excel("Data/boers.xlsx", sheet = "line + null zone new")
line_data$common_mean <- with(line_data, (placebo_mean+tcz_mean)/2)
line_data$null_lci <- with(line_data, common_mean - 0.25*abs((diff_uci-diff_lci)))
line_data$null_uci <- with(line_data, common_mean + 0.25*abs((diff_uci-diff_lci)))
knitr::kable(head(line_data, n=5))
time | placebo_mean | placebo_sd | placebo_lci | placebo_uci | placebo_n | tcz_mean | tcz_sd | tcz_lci | tcz_uci | tcz_n | diff | diff_lci | diff_uci | common_mean | null_lci | null_uci |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3 | -1.450 | 4.577092 | -2.846 | -0.054 | 43 | -1.057 | 4.852363 | -2.611 | 0.497 | 39 | 0.393 | -1.69 | 2.47 | -1.2535 | -2.2935 | -0.2135 |
8 | -1.038 | 5.436116 | -2.696 | 0.620 | 43 | -1.908 | 5.791626 | -3.717 | -0.099 | 41 | -0.870 | -3.31 | 1.57 | -1.4730 | -2.6930 | -0.2530 |
16 | -2.031 | 6.204627 | -3.969 | -0.093 | 41 | -3.221 | 5.921569 | -5.168 | -1.274 | 37 | -1.190 | -3.93 | 1.55 | -2.6260 | -3.9960 | -1.2560 |
24 | -2.071 | 6.713047 | -4.249 | 0.107 | 38 | -4.094 | 7.341894 | -6.508 | -1.680 | 37 | -2.023 | -5.26 | 1.22 | -3.0825 | -4.7025 | -1.4625 |
32 | -3.830 | 7.209972 | -6.303 | -1.357 | 34 | -5.089 | 7.493782 | -7.698 | -2.480 | 33 | -1.259 | -4.85 | 2.33 | -4.4595 | -6.2545 | -2.6645 |
theme_boers <- function(){
theme(text=element_text(family="Corbel", colour="black"),
#define font
plot.margin = margin(0.2,1,0,0,"cm"),
#prevent x axis labels from being cut off
plot.title = element_text(size=20),
#text size of the title
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
#we do not want automatic grid lines in the background
axis.text.x=element_text(size=20, colour="black"),
axis.text.y=element_text(size=20, colour="black"),
axis.title.x = element_text(size=20),
axis.title.y = element_text(size=20),
#define the size of the tick labels and axis titles
axis.line = element_line(colour = 'black', linewidth = 0.25),
axis.ticks = element_line(colour = "black", linewidth = 0.25),
#specify thin axes
axis.ticks.length = unit(4, "pt"),
axis.minor.ticks.length = unit(2, "pt"))
#minor ticks should be shorter than major ticks
}
ggplot(data=line_data) + theme_minimal() + theme_boers() +
annotate(geom="rect", xmin=48, xmax=100, ymin=-20, ymax=10, fill="#E2E9F0") + #crossover
annotate(geom="segment", x=0, xend=96, y=seq(-15,10,by=5), #background lines
yend=seq(-15,10,by=5), col="#E3E4E5", linewidth=0.5) +
scale_fill_identity() + #use specified colors
scale_color_identity() +
#null zone:
geom_ribbon(aes(x=time, ymin=null_lci, ymax=null_uci, fill="#CCCCCC"), colour=NA) +
#plot placebo data:
geom_line(data=subset(line_data, time<50), aes(x=time, y=placebo_mean),
colour="#EF8733", linewidth=1) + #plot mean over time (first half)
geom_line(data=subset(line_data, time>45), aes(x=time, y=placebo_mean),
colour="#183e7a", linewidth=1) + #plot mean over time (second half)
geom_point(data=subset(line_data, time<=48), aes(x=time, y=placebo_mean), shape=24,
colour="#EF8733", fill="#EF8733", size=3) + #plot points (first half)
geom_segment(data=subset(line_data, time<=48), #plot SD (first half)
aes(x=time, y=placebo_mean, yend=placebo_mean+placebo_sd), colour="#EF8733") +
geom_segment(data=subset(line_data, time>48), #plot SD (second half)
aes(x=time, y=placebo_mean, yend=placebo_mean+placebo_sd), colour="#183e7a") +
geom_segment(data=subset(line_data, time<=48), #plot CI (first half)
aes(x=time-1, xend=time+1, y=placebo_uci), colour="#EF8733") +
geom_segment(data=subset(line_data, time>48), #plot CI (second half)
aes(x=time-1, xend=time+1, y=placebo_uci), colour="#183e7a") +
geom_point(data=subset(line_data, time>48), aes(x=time, y=placebo_mean), shape=24,
colour="#183e7a", fill="#183e7a", size=3) +#plot point (second half)
#plot TCZ data:
geom_line(aes(x=time, y=tcz_mean), colour="#183e7a", linewidth=1) + #plot mean over time
geom_segment(aes(x=time, y=tcz_mean, yend=tcz_mean-tcz_sd), colour="#183e7a") + #plot SD
geom_segment(aes(x=time-1, xend=time+1, y=tcz_lci), colour="#183e7a") +
geom_point(aes(x=time, y=tcz_mean), shape=21, colour="#183e7a", fill="#183e7a", size=3) +
#specify axes and titles
coord_cartesian(xlim=c(0,100), ylim=c(-20,10), clip = "off") +
#specify range of x and y
scale_y_continuous(breaks=seq(-20, 10,by=5),
labels=c("–20","","–10","","0","","10"),
minor_breaks = seq(-20,10,by=1),
expand = c(0,0)) +
scale_x_continuous(breaks=seq(0,96,by=16),
labels=seq(0,96,by=16),
minor_breaks = seq(0,96,by=8),
expand = c(0,0)) +
annotate("text", x=48, y=-18, label="week", size=20/.pt, family="Corbel") +
annotate("text", x=8, y=-14, label="TCZ",
colour="#183e7a", hjust=0, size=20/.pt, family="Corbel") +
annotate("text", x=8, y=6, label="placebo",
colour="#EF8733", hjust=0, size=20/.pt, family="Corbel") +
annotate("text", x=64, y=6, label="open-label TCZ",
colour="#183e7a", hjust=0, size=20/.pt, family="Corbel") +
annotate("text", -5, 12, label="change in modified Rodnan skin score",
size=20/.pt, hjust=0, family="Corbel") +
guides(y = guide_axis(minor.ticks = TRUE), x = guide_axis(minor.ticks = TRUE)) +
xlab("") + ylab("") +
theme(plot.margin=margin(1.2,1,0,0,"cm"))
Survival graphs
First, we will load in some data.
Loading required package: ggpubr
Attaching package: 'survival'
The following object is masked from 'package:survminer':
myeloma
survival_data <- readxl::read_excel("Data/boers.xlsx", sheet = "survival (5)")
knitr::kable(head(survival_data, n=10))
time | event | treat |
---|---|---|
5.087 | 1 | TCZ |
8.076 | 1 | TCZ |
8.076 | 1 | TCZ |
11.956 | 1 | TCZ |
12.213 | 1 | TCZ |
13.315 | 1 | TCZ |
13.315 | 1 | TCZ |
23.078 | 1 | TCZ |
6.080 | 0 | TCZ |
14.939 | 0 | TCZ |
km_data <- surv_summary(survfit(Surv(time,event) ~ treat, data=survival_data), data=survival_data)
km_data <- rbind(data.frame("time"=c(0,0),"n.risk"=c(18,18),"n.event"=c(0,0),
"n.censor"=c(0,0), "surv"=c(1,1),"std.err"=c(0,0),
"upper"=c(1,1),"lower"=c(1,1),
"strata"=c("treat=placebo", "treat=TCZ"),
"treat"=c("placebo","TCZ")), km_data)
km_data$col <- with(km_data, ifelse(treat=="placebo","#020080", "#C00B08"))
censor_data <- subset(km_data, n.censor>0)
theme_boers <- function(){
theme(text=element_text(family="Corbel", colour="black"),
#define font
plot.margin = margin(0.2,1,0,0,"cm"),
#prevent x axis labels from being cut off
plot.title = element_text(size=20),
#text size of the title
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
#we do not want automatic grid lines in the background
axis.text.x=element_text(size=20, colour="black"),
axis.text.y=element_text(size=20, colour="black"),
axis.title.x = element_text(size=20),
axis.title.y = element_text(size=20),
#define the size of the tick labels and axis titles
axis.line = element_line(colour = 'black', linewidth = 0.25),
axis.ticks = element_line(colour = "black", linewidth = 0.25),
#specify thin axes
axis.ticks.length = unit(4, "pt"),
axis.minor.ticks.length = unit(2, "pt"))
#minor ticks should be shorter than major ticks
}
ggplot(data=km_data, aes(time, 100*surv, colour=col)) + theme_minimal() + theme_boers() +
annotate(geom="segment", x=0, xend=56, y=50,
yend=50, col="#E3E4E5") +
coord_cartesian(xlim=c(0,56), ylim=c(0,100), clip = "off") +
geom_step(linewidth=1.5) +
scale_color_identity() +
geom_segment(data=censor_data,
aes(x=time, xend=time, y=100*surv, yend=100*(surv+0.03),colour=col)) +
scale_y_continuous(breaks=seq(0,100,by=20),
labels=seq(0,100,by=20),
minor_breaks = seq(0,100,by=10),
expand = c(0,0)) +
scale_x_continuous(breaks=seq(0,56,by=8),
labels=seq(0,56,by=8),
minor_breaks = seq(0,56,by=4),
expand = c(0,0)) +
annotate("text", -5, 110, label="relapse-free (%)", size=20/.pt, hjust=0, family="Corbel") +
annotate("text", 40, 60, label="TCZ", colour="#C00B08", fontface=2,
size=20/.pt, hjust=0, family="Corbel") +
annotate("text", 40, 30, label="placebo", colour="#020080", fontface=2,
size=20/.pt, hjust=0, family="Corbel") +
guides(y = guide_axis(minor.ticks = TRUE), x=guide_axis(minor.ticks = TRUE)) +
theme(plot.margin=margin(1.5,1,0,0,"cm")) +
xlab("week") + ylab("")