Immunogenicity and safety of coadministration of COVID-19 and influenza vaccination among healthcare workers
Isabell Wagenhäuser1,2 ; Julia Reusch1,2 ; Alexander Gabel, PhD1 ; Anna Höhn1 ; Thiên-Trí Lâm, MD3 ; Giovanni Almanzar, MD4 ; Martina Prelog, MD, MSc4 ; Lukas B. Krone, MD, PhD5,6 ; Anna Frey, MD2 ; Alexandra Schubert-Unkmeir, MD3 ; Lars Dölken, MD7 ; Stefan Frantz, MD2 ; Oliver Kurzai, MD3,8 ; Ulrich Vogel, MD1,3 ; Nils Petri, MD2* ; Manuel Krone, MD, MScPH1,3*
Affiliations:
1 Infection Control Unit, University Hospital Wuerzburg,
Wuerzburg, Germany
2 Department of Internal Medicine I,
University Hospital Wuerzburg, Wuerzburg, Germany
3
Institute for Hygiene and Microbiology, University of Wuerzburg, Wuerzburg, Germany
4 Paediatric Rheumatology/Special Immunology, Department of Paediatrics,
University Hospital Wuerzburg, Wuerzburg, Germany
5
Department of Physiology, Anatomy and Genetics, University of Oxford, Oxford, UK
6 University Hospital of Psychiatry and Psychotherapy, University of Bern, Bern, Switzerland
7 Institute for Virology and Immunobiology, University of Wuerzburg, Wuerzburg, Germany
8 Leibniz Institute for Natural Product Research and Infection Biology – Hans-Knoell-Institute, Jena, Germany
* both authors contributed equally
med_iqr <- function (x ){
med_x <- round(median(x , na.rm = T ), 1 )
iqr_x <- round(quantile(x , probs = c(0.25 , 0.75 ), na.rm = T ), 1 )
res <- " -"
if (! is.na(med_x )){
res <- paste0(med_x , " (" , iqr_x [1 ], " -" , iqr_x [2 ]," )" )
}
return (res )
}
number_percent <- function (df , gr1 , gr2 ){
df %> % group_by(!! sym(gr1 ), !! sym(gr2 )) %> %
summarise(n = n()) %> %
mutate(perc = round(n / sum(n ) * 100 , 2 )) %> %
mutate(comb = paste0(n , " (" , perc ," %)" )) %> %
tidyr :: pivot_wider(id_cols = c(gr1 , gr2 ), names_from = gr1 , values_from = " comb" ) %> %
mutate(across(.cols = c(- !! sym(gr2 )),.fns = function (x ) replace(x , which(is.na(x )), " 0 (0.00%)" )))
}
number_percent_one_factor <- function (df , gr1 ){
df %> % group_by(!! sym(gr1 )) %> %
summarise(n = n(), .groups = " drop" ) %> %
mutate(perc = round(n / sum(n ) * 100 , 2 )) %> %
mutate(comb = paste0(n , " (" , perc ," %)" )) %> %
tidyr :: pivot_wider(id_cols = c(gr1 ), names_from = gr1 , values_from = " comb" ) # %>%
# mutate(across(.cols = c(-!!sym(gr1)),.fns = function(x) replace(x, which(is.na(x)), "0 (0.00%)")))
}
mut_num_perc <- function (x , char_sel ){
abs <- sum(x == char_sel )
rel <- round(abs / length(x )* 100 , digits = 2 )
return (paste0(abs , " (" , rel , " %)" ))
}
fisher_test_table <- function (df , gr_row , gr_col ){
ft_table <- df %> % group_by(!! sym(gr_row ), !! sym(gr_col )) %> % count(name = " Number of Subjects" ) %> %
tidyr :: pivot_wider(id_cols = c(gr_col , " Number of Subjects" ), names_from = gr_row , values_from = " Number of Subjects" )
ft_res <- fisher.test(ft_table [,- 1 ])
kable_table <- df %> % group_by(!! sym(gr_row ), !! sym(gr_col )) %> % count(name = " n" ) %> %
group_by(!! sym(gr_col )) %> % mutate(val = paste0(n , " (" , round(n / sum(n ) * 100 , 2 ), " %)" )) %> %
tidyr :: pivot_wider(id_cols = c(gr_row , " val" , gr_col ), names_from = gr_col , values_from = " val" )
kable_table <- cbind(kable_table , " Odds-Ratio" = round(ft_res $ estimate , 2 ), " P-value" = ft_res $ p.value )
kable_table <- kable_table %> % mutate(`P-value` = dplyr :: case_when(
`P-value` > = 0.01 ~ as.character(round(`P-value` , 2 )),
`P-value` < 0.0001 ~ " < 0.0001" ,
`P-value` < 0.001 ~ " < 0.001" ,
`P-value` < 0.01 ~ " < 0.01" ))
knitr :: kable(kable_table , align = " c" ) %> %
kableExtra :: kable_styling(full_width = F , position = " left" )%> %
kableExtra :: column_spec(1 , bold = T ) %> %
kableExtra :: collapse_rows(columns = 3 : 5 , valign = " middle" )
}
chisq_test_table <- function (df , gr_row , gr_col ){
chi_table <- df %> % group_by(!! sym(gr_row ), !! sym(gr_col )) %> % count(name = " Number of Subjects" ) %> %
tidyr :: pivot_wider(id_cols = c(gr_row , " Number of Subjects" ), names_from = gr_col , values_from = " Number of Subjects" )
chisq_res <- chisq.test(chi_table [,- 1 ])
kable_table <- df %> % group_by(!! sym(gr_row ), !! sym(gr_col )) %> % count(name = " n" ) %> %
group_by(!! sym(gr_col )) %> % mutate(val = paste0(n , " (" , round(n / sum(n ) * 100 , 2 ), " %)" )) %> %
tidyr :: pivot_wider(id_cols = c(gr_row , " val" , gr_col ), names_from = gr_col , values_from = " val" )
knitr :: kable(cbind(kable_table , " Odds-Ratio" = " -" , " P-value" = round(chisq_res $ p.value , 2 )), align = " c" ) %> %
kableExtra :: kable_styling(full_width = F , position = " left" )%> %
kableExtra :: column_spec(1 , bold = T ) %> %
kableExtra :: collapse_rows(columns = dim(kable_table )[2 ]: (dim(kable_table )[2 ] + 2 ), valign = " middle" )
}
model_specifics <- function (model , data ){
prds <- model %> % predict(data )
rmse <- caret :: RMSE(prds , data $ logIgG )
r2 <- caret :: R2(prds , data $ logIgG )
list (RMSE = rmse , R2 = r2 )
}
fisher_tests_gr <- function (df , gr1 , var_expr ){
df_subset <- df %> % select(!! sym(gr1 ), dplyr :: matches(var_expr )) %> % na.omit()
fisher_tests <- c()
for (nw in colnames(df_subset %> % select(dplyr :: matches(var_expr )))){
conf_mat <- df_subset %> % dplyr :: group_by(!! sym(gr1 ), !! sym(nw )) %> %
count(name = " n" ) %> % ungroup() %> %
tidyr :: pivot_wider(id_cols = c(gr1 , nw ), values_from = c(" n" ), names_from = c(nw ))
fisher_res <- broom :: tidy(fisher.test(conf_mat [,- 1 ], alternative = " two.sided" ))
colnames(conf_mat )[- 1 ] <- c(" gr2.1" , " gr2.2" )
fisher_tests <- rbind(fisher_tests , cbind(group1 = conf_mat %> % pull(!! sym(gr1 )) %> % as.character(), group2 = nw , conf_mat [,- 1 ], fisher_res ))
}
return (fisher_tests )
}
fisher_plot_odds <- function (fisher_test_df , ylab_add = " Coadministration" , wrap = F , ylim = NULL ){
fisher_plt_df <- fisher_test_df %> %
select(group2 , estimate , matches(" conf|super" ), p.value ) %> %
unique() %> % mutate(p.adj = p.adjust(p.value , " BY" ))
odds_plot <- ggplot2 :: ggplot(data = fisher_plt_df , ggplot2 :: aes(x = group2 , y = estimate ))
if (wrap ){
odds_plot <- odds_plot + ggplot2 :: facet_wrap(~ super_group , nrow = 2 )
}
odds_plot <- odds_plot +
ggplot2 :: geom_point(cex = 3 ) +
ggplot2 :: geom_errorbar(ggplot2 :: aes(ymin = conf.low , ymax = conf.high ), width = 0.5 ,
position = ggplot2 :: position_dodge2(), show.legend = FALSE ) +
ggplot2 :: theme_bw() +
ggplot2 :: scale_x_discrete(labels = c(" Local reactions" , " Headache" , " Muscle Pain" , " Fever and/or Chills" , " Fatigue" , " Other s.e." )) +
ggsci :: scale_color_nejm() +
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 12 , colour = " black" ),
axis.text.x = ggplot2 :: element_text(angle = 45 , hjust = 1 ),
axis.title = ggplot2 :: element_text(face = " bold" , size = 14 ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 12 ),
legend.position = " bottom" ,
strip.text = ggplot2 :: element_text(size = 14 , face = " bold" ),
strip.background = ggplot2 :: element_rect(fill = " white" ))+
ggplot2 :: ylab(paste0(" OR " , ylab_add )) +
ggplot2 :: xlab(" side effects" )
if (! is.null(ylim )){
odds_plot <- odds_plot + ggplot2 :: ylim(ylim )
}
if (dim( fisher_plt_df %> % filter(p.adj < 0.05 ))[1 ] > 0 ){
odds_plot <- odds_plot + ggplot2 :: geom_text(data = fisher_plt_df %> % filter(p.adj < 0.05 ), ggplot2 :: aes(x = group2 , y = conf.high , label = paste0(" italic(p)== " ,round(p.adj , 2 ))), vjust = - 0.5 , parse = T )
}
odds_plot
}
barplot_sideeffects_percentage <- function (p.adj_fisher_tests_df , wrap = F ){
plt_df <- c()
if (wrap ){
plt_df <- p.adj_fisher_tests_df %> % group_by(super_group , group1 , group2 ) %> %
mutate(n = gr2.1 + gr2.2 ,
percentage = round(gr2.1 / n * 100 , 2 )) %> %
select(group1 , group2 , percentage , p.adjusted )
}else {
plt_df <- p.adj_fisher_tests_df %> % group_by(group1 , group2 ) %> %
mutate(n = gr2.1 + gr2.2 ,
percentage = round(gr2.1 / n * 100 , 2 )) %> %
select(group1 , group2 , percentage , p.adjusted )
}
p_val_data <- plt_df %> % mutate(group1 = plt_df $ group1 [1 ]) %> %
select(group2 , p.adjusted , percentage ) %> %
mutate(percentage = max(percentage )) %> %
unique() %> % ungroup()
bar_plt <- ggplot2 :: ggplot(data = plt_df , ggplot2 :: aes(x = group2 , y = percentage , fill = group1 ))
if (wrap ){
bar_plt <- bar_plt + ggplot2 :: facet_wrap(~ super_group , nrow = 2 )
}
bar_plt <- bar_plt +
ggplot2 :: geom_bar(stat = " identity" , position = ggplot2 :: position_dodge2()) +
ggplot2 :: xlab(" Side effects" ) +
ggplot2 :: ylab(" Percentage of participants" ) +
ggplot2 :: theme_bw() +
ggsci :: scale_fill_nejm() +
ggplot2 :: scale_x_discrete(labels = c(" Local reactions" ,
" Headache" , " Muscle Pain" , " Fever and/or Chills" , " Fatigue" , " Other" )) +
ggplot2 :: scale_y_continuous(expand = c(0 ,1 ), limits = c(0 ,100 )) +
ggplot2 :: guides(fill = ggplot2 :: guide_legend(title = " Effect" )) +
ggplot2 :: theme(axis.title = ggplot2 :: element_text(color = " black" , size = 13 , face = " bold" ),
axis.text = ggplot2 :: element_text(color = " black" , size = 12 ),
axis.text.x = ggplot2 :: element_text(angle = 45 , hjust = 1 , vjust = 1 ),
strip.text = ggplot2 :: element_text(size = 14 , face = " bold" ),
strip.background = ggplot2 :: element_rect(fill = " white" ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 10 ),
axis.title.x = ggplot2 :: element_blank(),
legend.position = " bottom" ,
legend.justification = c(" left" , " top" ),
legend.box.just = " left" ,
legend.margin = ggplot2 :: margin(6 , 6 , 6 , 6 ),
legend.background = ggplot2 :: element_rect(fill = NA ))+
ggplot2 :: geom_text(data = p_val_data ,
mapping = ggplot2 :: aes(x = group2 , y = percentage + 1 , label = paste0(" italic(p)== " , round(p.adjusted , digits = 3 ))),
hjust = 0.5 , vjust = 0 , size = 4 , parse = T )
bar_plt
}
External Packages and folder structure
library(dplyr )
library(ggplot2 )
library(lubridate )
library(glmnet )
library(emmeans )
library(knitr ) # required for kable
library(kableExtra ) # required for kableExtra
# required libraries:
# ggstance
# broom.mixed
# jtools
# effects
# sjPlot
# rstatix
super_dir <- " ./"
plot.dir <- file.path(super_dir , " plots" )
data.dir <- file.path(super_dir , " data" )
if (! file.exists(data.dir )){
dir.create(data.dir , recursive = T )
}
for (plt_format in c(" png" , " pdf" , " svg" )){
if (! file.exists(file.path(plot.dir , plt_format ))){
dir.create(file.path(plot.dir , plt_format ), recursive = T )
}
}
df_coad <- readRDS(file.path(data.dir , " covacser_data_coadministration.rds" ))
Feature
Stats
Number of Subjects
1231
Age
41 (30-53)
Weight
69 (60-80)
Height
169 (164-175)
BMI
23.8 (21.6-27.1)
Smoking
150 (12.19%)
Side effects
1059 (86.03%)
Immune deficiency
30 (2.44%)
Days_Vacc_12
21 (21-21)
Days_Vacc_23
266 (241-290)
Days_Vacc3_Serum
18 (15-24)
BNT162b2mRNA
996 (80.91%)
mRNA-1273
235 (19.09%)
Coadministration
249 (20.23%)
IgG
2008 (1268.8-3082.1)
Feature
female
male
Number of Subjects
1015 (82%)
216 (18%)
Age
41 (30-53)
40.5 (32-50)
Weight
66 (59-76)
82 (73.8-92)
Height
168 (163-172)
180 (176-185)
BMI
23.6 (21.3-27)
24.6 (22.7-27.5)
Smoking
122 (12.02%)
28 (12.96%)
Side effects
887 (87.39%)
172 (79.63%)
Immune deficient
29 (2.86%)
1 (0.46%)
Days_Vacc_12
21 (21-21)
21 (21-22)
Days_Vacc_23
265 (239-289)
274.5 (249.2-293)
Days_Vacc3_Serum
18 (15-24)
18 (15-24)
BNT162b2mRNA
812 (80%)
184 (85.19%)
mRNA-1273
203 (20%)
32 (14.81%)
Coadministration
187 (18.42%)
62 (28.7%)
IgG
2024.4 (1287.3-3082.1)
1980.8 (1157.2-3029.7)
Separated by coadministration
Feature
Coadministration
No Coadministration
p
p.adjust
Number of Subjects
249 (20%)
982 (80%)
NA
NA
age
38 (30-51)
41 (31-53)
0.08760
0.3974850
weight
70 (62-83)
68 (60-80)
0.02560
0.1548800
height
170 (165-176)
168 (164-174)
0.00307
0.0557205
bmi
23.8 (21.7-27.3)
23.8 (21.5-27.1)
0.53100
1.0000000
gender
187 (75.1%)
828 (84.32%)
NA
NA
smoking
32 (12.85%)
118 (12.02%)
NA
NA
Side effects
202 (81.12%)
857 (87.27%)
NA
NA
Immune deficiency
3 (1.2%)
27 (2.75%)
NA
NA
days_vacc12
21 (21-21)
21 (21-21)
0.52700
1.0000000
days_vacc23
260 (231-288)
267 (243-290.8)
0.01870
0.1548800
time_serum_coadmin
18 (15-24)
18 (15-24)
0.67200
1.0000000
BNT162b2mRNA
225 (90.36%)
771 (78.51%)
NA
NA
mRNA-1273
24 (9.64%)
211 (21.49%)
NA
NA
IgG
1605 (1078-2504.7)
2150.2 (1341.1-3242.3)
NA
NA
fisher_test_table(df = df_coad , gr_col = " coadmin" , gr_row = " vaccine" )
vaccine
Coadministration
No Coadministration
Odds-Ratio
P-value
BNT162b2mRNA
225 (90.36%)
771 (78.51%)
2.56
\< 0.0001
mRNA-1273
24 (9.64%)
211 (21.49%)
fisher_test_table(df = df_coad , gr_col = " coadmin" , gr_row = " gender" )
gender
Coadministration
No Coadministration
Odds-Ratio
P-value
female
187 (75.1%)
828 (84.32%)
0.56
\< 0.01
male
62 (24.9%)
154 (15.68%)
fisher_test_table(df = df_coad , gr_col = " coadmin" , gr_row = " smoking" )
smoking
Coadministration
No Coadministration
Odds-Ratio
P-value
smoker
32 (12.85%)
118 (12.02%)
1.08
0.74
non-smoker
217 (87.15%)
864 (87.98%)
chisq_test_table(df = df_coad , gr_col = " coadmin" , gr_row = " risk" )
risk
Coadministration
No Coadministration
Odds-Ratio
P-value
false
156 (62.65%)
581 (59.16%)
0.41
rather false
59 (23.69%)
237 (24.13%)
partly
24 (9.64%)
100 (10.18%)
rather true
5 (2.01%)
46 (4.68%)
true
5 (2.01%)
18 (1.83%)
fisher_test_table(df = df_coad , gr_col = " coadmin" , gr_row = " sideeffects" )
sideeffects
Coadministration
No Coadministration
Odds-Ratio
P-value
TRUE
202 (81.12%)
857 (87.27%)
0.63
0.02
FALSE
47 (18.88%)
125 (12.73%)
immune system
Coadministration
No Coadministration
Odds-Ratio
P-value
deficient
3 (1.2%)
27 (2.75%)
0.43
0.25
competent
246 (98.8%)
955 (97.25%)
df_coad %> % ggplot2 :: ggplot(ggplot2 :: aes(x = age )) +
ggplot2 :: facet_wrap(~ coadmin ) +
ggplot2 :: geom_histogram(bins = 40 , col = " black" ) +
ggplot2 :: xlab(" Age of subjects" ) +
ggplot2 :: ylab(" Number of subjects" ) +
ggplot2 :: theme_bw() +
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 12 ),
axis.title = ggplot2 :: element_text(face = " bold" ),
strip.text = ggplot2 :: element_text(face = " bold" , size = 12 )) +
ggplot2 :: geom_text(data = df_coad %> % group_by(coadmin ) %> % count(),
mapping = ggplot2 :: aes(x = 45 , y = 50 , label = paste0(" Subjects: " ,n )),
hjust = 0.5 ,
vjust = 0 , size = 4 ) +
ggplot2 :: geom_text(data = df_coad %> % group_by(coadmin ) %> % summarise(age = median(age )),
mapping = ggplot2 :: aes(x = 45 , y = 45 , label = paste0(" Median Age: " ,round(age ))),
hjust = 0.5 ,
vjust = 0 , size = 4 )
ggsave(filename = file.path(plot.dir ," Histogramm_Altersverteilung.pdf" ), device = " pdf" , width = 6 , height = 5 )
ggsave(filename = file.path(plot.dir ," svg/Histogramm_Altersverteilung.svg" ), device = " svg" , width = 6 , height = 5 )
Feature
BNT162b2mRNA
mRNA-1273
N
996 (81%)
235 (19%)
Age
38.5 (29-52)
46 (39-55)
Weight
69 (60-80)
68 (60-79)
Height
169 (164-175)
168 (164-173)
BMI
23.8 (21.6-27.1)
23.8 (21.5-27)
Gender (female)
812 (81.53%)
203 (86.38%)
Smoking
127 (12.75%)
23 (9.79%)
Days_Vacc_12
21 (21-21)
21 (21-21)
Days_Vacc_23
267 (242-290)
265 (237-294)
Days_Vacc3_Serum
18 (15-22)
21 (16-27)
Coadministration
225 (22.59%)
24 (10.21%)
IgG
1888.4 (1192.6-2916.8)
2655.8 (1698.7-3987.9)
Vaccine: relative frequencies
df_coad %> % group_by(coadmin , vaccine ) %> % count() %> % group_by(coadmin ) %> % mutate(n = n / sum(n )) %> %
ggplot2 :: ggplot(ggplot2 :: aes(x = vaccine , y = n , fill = coadmin )) +
ggplot2 :: geom_bar(stat = " identity" , position = ggplot2 :: position_dodge()) +
ggplot2 :: xlab(" Vaccine" ) +
ggplot2 :: ylab(" relative frequency of subjects" ) +
ggplot2 :: theme_bw() +
ggsci :: scale_fill_nejm()+
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 12 , colour = " black" ),
axis.title = ggplot2 :: element_text(face = " bold" , size = 14 ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 12 ),
legend.position = " bottom" ) +
ggplot2 :: guides(color = ggplot2 :: guide_legend(override.aes = list (shape = 22 , size = 8 , stroke = 1 ), ncol = 2 ))
ggsave(filename = file.path(plot.dir ," png/Barplot_Vaccine.png" ), device = " png" , width = 6 , height = 6 , dpi = 300 )
ggsave(filename = file.path(plot.dir ," svg/Barplot_Vaccine.svg" ), device = " svg" , width = 6 , height = 6 , dpi = 300 )
df_coad %> %
ggplot2 :: ggplot(ggplot2 :: aes(y = coadmin , x = date_vacc3 , col = vaccine )) +
ggplot2 :: geom_point(position = ggplot2 :: position_jitterdodge(jitter.height = 0.2 )) +
ggplot2 :: theme_bw() +
ggplot2 :: ylab(" " ) +
ggplot2 :: xlab(" Date of vaccination" ) +
ggsci :: scale_color_nejm() +
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 12 , colour = " black" ),
axis.text.x = ggplot2 :: element_text(angle = 45 , vjust = 1 , hjust = 1 ),
axis.title = ggplot2 :: element_text(face = " bold" , size = 14 ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 12 ),
legend.position = " bottom" ) +
ggplot2 :: guides(color = ggplot2 :: guide_legend(override.aes = list (shape = 20 , size = 8 , stroke = 1 ), ncol = 2 ))
ggsave(filename = file.path(plot.dir ," png/Impfdaten_Vakzin_scatter.png" ), device = " png" , width = 6 , height = 6 , dpi = 300 )
ggsave(filename = file.path(plot.dir ," svg/Impfdaten_Vakzin_scatter.svg" ), device = " svg" , width = 6 , height = 6 , dpi = 300 )
Comparison time between serum and vaccination
gr_stats <- rbind(df_coad %> % group_by(vaccine ) %> % summarise(" Med ± IQR" = med_iqr(time_serum_coadmin )) %> % rename(gr = " vaccine" ),
df_coad %> % group_by(coadmin ) %> % summarise(" Med ± IQR" = med_iqr(time_serum_coadmin )) %> % rename(gr = " coadmin" ),
df_coad %> % group_by(vaccine , coadmin ) %> % summarise(" Med ± IQR" = med_iqr(time_serum_coadmin )) %> %
mutate(gr = paste0(vaccine , " :" , coadmin )) %> % ungroup() %> % select(- vaccine , - coadmin ))
time_test_table <- rbind(df_coad %> % rstatix :: wilcox_test(time_serum_coadmin ~ vaccine ) %> % select(- .y. ),
df_coad %> % rstatix :: wilcox_test(time_serum_coadmin ~ coadmin ) %> % select(- .y. ),
df_coad %> % group_by(vaccine ) %> % rstatix :: wilcox_test(time_serum_coadmin ~ coadmin ) %> %
mutate(group1 = paste0(vaccine , " :" , group1 ),
group2 = paste0(vaccine , " :" , group2 )) %> %
select(- vaccine , - .y. ),
df_coad %> % group_by(coadmin ) %> % rstatix :: wilcox_test(time_serum_coadmin ~ vaccine ) %> %
mutate(group1 = paste0(group1 , " :" , coadmin ),
group2 = paste0(group2 , " :" , coadmin )) %> %
select(- coadmin , - .y. )) %> % inner_join(gr_stats , by = c(" group1" = " gr" )) %> %
inner_join(gr_stats , by = c(" group2" = " gr" )) %> %
rename(" Median(gr1) (IQR)" = `Med ± IQR.x` ,
" Median(gr2) (IQR)" = `Med ± IQR.y` ) %> %
relocate(group1 , group2 , matches(" Med" ))
time_test_table <- cbind(time_test_table , p.adjusted = p.adjust(time_test_table $ p , method = " holm" ))
time_test_table %> % knitr :: kable() %> %
kableExtra :: kable_paper() %> %
kableExtra :: pack_rows(" Subgroups: " , 3 , 6 )
group1
group2
Median(gr1) (IQR)
Median(gr2) (IQR)
n1
n2
statistic
p
p.adjusted
BNT162b2mRNA
mRNA-1273
18 (15-22)
21 (16-27)
996
235
95452.0
9.80e-06
5.87e-05
Coadministration
No Coadministration
18 (15-24)
18 (15-24)
249
982
120148.0
6.72e-01
1.00e+00
Subgroups:
BNT162b2mRNA:Coadministration
BNT162b2mRNA:No Coadministration
17 (15-22)
18 (15-22)
225
771
87112.5
9.21e-01
1.00e+00
mRNA-1273:Coadministration
mRNA-1273:No Coadministration
22 (15-27.2)
20 (16-27)
24
211
2525.5
9.85e-01
1.00e+00
BNT162b2mRNA:Coadministration
mRNA-1273:Coadministration
17 (15-22)
22 (15-27.2)
225
24
2309.0
2.42e-01
9.68e-01
BNT162b2mRNA:No Coadministration
mRNA-1273:No Coadministration
18 (15-22)
20 (16-27)
771
211
65815.0
1.94e-05
9.70e-05
Overview IgG concentrations
df_coad %> % group_by(coadmin ) %> % mutate(IgG = log10(IgG )) %> %
summarise(geo_mean = 10 ^ (mean(IgG )),
minIgG = min(10 ^ IgG ),
maxIgG = max(10 ^ IgG ),
IQR_IgG = IQR(10 ^ IgG ),
`N(IgG > 31.5)` = sum(10 ^ IgG > 31.5 ),
N = n()) %> %
mutate(sumN = sum(N ),
`% N/sumN` = N / sumN * 100 ,
`% N(IgG > 31.5)/N` = `N(IgG > 31.5)` / N * 100 ) %> %
mutate(across(.fns = ~ format(x = .x , digits = 2 , nsmall = 2 ))) %> %
dplyr :: relocate(coadmin , N , sumN , geo_mean , minIgG , maxIgG , IQR_IgG , `% N/sumN` , `N(IgG > 31.5)` , `% N(IgG > 31.5)/N` ) %> % knitr :: kable() %> %
kableExtra :: kable_paper()
coadmin
N
sumN
geo_mean
minIgG
maxIgG
IQR_IgG
% N/sumN
N(IgG \> 31.5)
% N(IgG \> 31.5)/N
Coadministration
249
1231
1599.68
239.06
18541.53
1426.63
20.23
249
100.00
No Coadministration
982
1231
2036.93
17.76
21287.91
1901.22
79.77
981
99.90
Distribution of IgG titres
plot_density <- function (){
igg_df <- df_coad %> % select(IgG , logIgG ) %> % tidyr :: pivot_longer(cols = c(IgG , logIgG ), names_to = " transform" , values_to = " values" )
theo_params <- igg_df %> % group_by(transform ) %> % summarise(mu_est = mean(values ),
sd_est = sd(values ),
xmin = min(values ),
xmax = max(values ))
dens_plts <- list ()
igg_names <- unique(igg_df $ transform )
mains <- c(" Density of IgG titres" , " Density of logarithmized IgG titres" )
xlabs <- c(" IgG" , " log10(IgG)" )
m <- rbind(c(0 , 0.5 , 0 , 1 ),
c(0.5 , 1 , 0 , 1 ))
split.screen(m )
for (i in seq_along(igg_names )){
screen(i )
if (i == 1 ){
par(mar = c(4.1 , 4.1 , 2.1 , .5 ))
}
if (i == 2 ){
par(mar = c(4.1 , 4.1 , 2.1 , .5 ))
}
values <- df_coad %> % pull(!! sym(igg_names [i ]))
x_vals <- seq(min(values ), max(values ), length.out = 1000 )
hist(values , xlab = xlabs [i ], prob = T , col = " white" , main = mains [i ], breaks = 30 )
lines(x = x_vals , y = dnorm(x = x_vals , mean = mean(values ), sd = sd(values )), lty = 1 , lwd = 2 )
box()
}
close.screen(all.screens = TRUE )
}
png(filename = file.path(plot.dir , paste0(" png/Distribution_IgG_titres.png" )),units = " px" , width = 2500 , height = 1000 , res = 300 )
plot_density()
close.screen(all.screens = TRUE )
dev.off()
svg(filename = file.path(plot.dir , paste0(" svg/Distribution_IgG_titres.svg" )), width = 10 , height = 4 )
plot_density()
close.screen(all.screens = TRUE )
dev.off()
plot_density()
Multiple regression analysis
model trained with REML (Re stricted M aximum L ikelihood)
weights are adjusted with nlme::varPower
because within-group
homoscedasticity cannot be guaranteed due to differing sample
sizes
model with interaction and without interaction between vaccine and
coadministration
df_test <- df_coad %> % select(IgG , logIgG , AgeCategory , gender , coadmin , time_serum_coadmin , smoking , risk , vaccine , sideeffects )
gls_mod <- nlme :: gls(logIgG ~ AgeCategory + gender + smoking + coadmin + vaccine + time_serum_coadmin + risk + sideeffects ,
data = df_test ,
weights = nlme :: varPower())
Estimated marginal means from linear model
mod_means <- modelbased :: get_emmeans(gls_mod , at = c(" vaccine" , " coadmin" )) %> % as_tibble()
int_plt_mm <- mod_means %> % ggplot2 :: ggplot(ggplot2 :: aes(x = coadmin , y = 10 ^ emmean , col = vaccine )) +
ggplot2 :: geom_errorbar(ggplot2 :: aes(ymax = 10 ^ upper.CL , ymin = 10 ^ lower.CL ), width = 0.4 ) +
ggplot2 :: geom_point(size = 2 ) +
ggplot2 :: geom_line(ggplot2 :: aes(group = vaccine )) +
ggplot2 :: scale_y_log10(limits = c(1000 , 4000 ), breaks = c(1000 , 2000 , 3000 , 4000 ), labels = c(1000 , 2000 , 3000 , 4000 )) +
ggplot2 :: annotation_logticks(sides = " l" ) +
ggplot2 :: xlab(" " ) +
ggplot2 :: ylab(" Anti-SARS-CoV-2-Spike IgG [BAU/ml]" ) +
ggplot2 :: theme_bw() +
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 14 , colour = " black" ),
axis.title = ggplot2 :: element_text(face = " bold" , size = 12 ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 16 ),
legend.position = " bottom" )
int_plt_mm
ggsave(plot = int_plt_mm , filename = file.path(plot.dir ," png/Interaction_marginal_means_1.png" ), device = " png" , width = 6 , height = 6 , dpi = 300 )
ggsave(plot = int_plt_mm , filename = file.path(plot.dir ," svg/Interaction_marginal_means_1.svg" ), device = " svg" , width = 6 , height = 6 , dpi = 300 )
Check assumptions for multiple regression analysis
Test for Autocorrelation (Durbin-Watson)
model_residuals <- as.numeric(residuals(gls_mod ))
dw_stat <- car :: durbinWatsonTest(model_residuals )
# Calculate P-value based on permutation
n_obs <- length(model_residuals )
n_samplings <- 1000
mu <- fitted.values(gls_mod )
X_model <- model.matrix(logIgG ~ AgeCategory + gender + smoking + coadmin + vaccine + time_serum_coadmin + risk + sideeffects ,
data = df_test )
sampled_data <- matrix (sample(model_residuals , n_obs * n_samplings , replace = TRUE ), n_obs , n_samplings ) + matrix (mu , n_obs , n_samplings )
E <- residuals(nlme :: gls(sampled_data ~ X_model - 1 , weights = nlme :: varPower()))
dw_sampled <- apply(E , 2 , car :: durbinWatsonTest )
p_value_dw <- (sum(dw_sampled > dw_stat ))/ n_samplings
p_value_dw <- 2 * (min(p_value_dw , 1 - p_value_dw ))
hist(dw_sampled , breaks = 50 , freq = T , main = " Histogram sampled DW statistics" , xlab = " Sampled DW values" , col = " white" )
abline(v = dw_stat , lwd = 3 , col = " red" )
Durbin-Watson-Test for autocorrelation (no autocorrelation):
Test statistic: d = 1.93
P-value: p = 0.24
x_vals <- seq(min(model_residuals ), max(model_residuals ), length.out = 1000 )
hist(model_residuals , xlab = " Residuals" , prob = T , col = " white" , main = expression(' Density of residuals' ), breaks = 30 )
lines(x = x_vals , y = dnorm(x = x_vals , mean = mean(model_residuals ), sd = sd(model_residuals )), lty = 1 , lwd = 2 )
png(filename = file.path(plot.dir , " png/histogram_residuals.png" ), units = " px" , width = 1600 , height = 1600 , res = 300 )
hist(model_residuals , xlab = " Residuals" , prob = T , col = " white" , main = expression(' Density of residuals' ), breaks = 30 )
lines(x = x_vals , y = dnorm(x = x_vals , mean = mean(model_residuals ), sd = sd(model_residuals )), lty = 1 , lwd = 2 )
dev.off()
svg(filename = file.path(plot.dir , " svg/histogram_residuals.svg" ), width = 6 , height = 6 )
hist(model_residuals , xlab = " Residuals" , prob = T , col = " white" , main = expression(' Density of residuals' ), breaks = 30 )
lines(x = x_vals , y = dnorm(x = x_vals , mean = mean(model_residuals ), sd = sd(model_residuals )), lty = 1 , lwd = 2 )
dev.off()
data.frame (fit = mu , residuals = model_residuals ) %> %
ggplot2 :: ggplot(aes(x = fit , y = residuals )) +
ggplot2 :: geom_point(alpha = 0.75 , pch = 20 , size = 2 ) +
ggplot2 :: xlab(" Fitted values based on linear model" ) +
ggplot2 :: ylab(" Residuals from linear model" ) +
ggplot2 :: theme_bw() +
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 14 , colour = " black" ),
axis.title = ggplot2 :: element_text(face = " bold" , size = 12 ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 16 ),
legend.position = " bottom" )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " png" , " Regression_model_residual_variances.png" ), device = " png" , width = 10 , height = 8 , dpi = 300 )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " svg" , " Regression_model_residual_variances.svg" ), device = " svg" , width = 10 , height = 8 , dpi = 300 )
Coefficients of the multiple regression model
sum_gls <- summary(gls_mod )
glm_p_values <- cbind(sum_gls $ tTable , p.adj = p.adjust(sum_gls $ tTable [,4 ], method = " BY" ))
anova_gls <- as.data.frame(anova(gls_mod ))
anova_gls <- cbind(anova_gls , p.adj = p.adjust(anova_gls $ `p-value` , method = " BY" ))
anova_gls <- anova_gls %> % mutate(p_plot = dplyr :: case_when(p.adj < 1e-4 ~ " < 0.0001" ,
p.adj > 1e-4 & p.adj < 1e-3 ~ " < 0.001" ,
p.adj > 1e-3 & p.adj < 1e-2 ~ " < 0.01" ,
p.adj > 1e-2 & p.adj < 0.05 ~ " < 0.05" ,
TRUE ~ format(round(p.adj , 2 ))
))
y_hat_igg <- predict(gls_mod , interval = " prediction" )
rsquare_cv <- cor(df_test $ logIgG , y_hat_igg )^ 2
anova_gls %> % knitr :: kable() %> %
kableExtra :: kable_paper()
Posthoc tests: Pairwise comparisons within discrete factors
compare subgroups within discrete factors
estimate marginal means for each factor and compare the subgroups
entities <- c(" AgeCategory" , " gender" , " coadmin" , " vaccine" , " smoking" , " sideeffects" , " risk" , " vaccine + coadmin" )
marg_list <- list ()
for (i in seq_along(entities )){
marginal <- emmeans(gls_mod , eval(parse( text = paste0(" ~ " , entities [i ]))), rg.limit = 160000 , weights = " proportional" )
marg_list [[i ]] <- as.data.frame(pairs(marginal ))
}
names(marg_list ) <- entities
post_hoc_comp <- do.call(" rbind" , marg_list )
post_hoc_comp $ contrast <- gsub(pattern = " \\ (|\\ )" , replacement = " " , x = post_hoc_comp $ contrast )
post_hoc_comp <- cbind(post_hoc_comp , p.adj = p.adjust(post_hoc_comp $ p.value , method = " BY" ))
risk_labels <- paste0(" Be at Risk: " , apply(combn(x = c(" False" , " Rather not true " , " Partly" , " Rather true" , " True" ), m = 2 ), 2 , function (col_el ){
paste0(col_el , collapse = " vs. " )
}))
coadmin_labels <- paste0(apply(combn(x = c(" BNT162b2mRNA:Coadministration" , " mRNA-1273:Coadministration" , " BNT162b2mRNA:No Coadministration" , " mRNA-1273:No Coadministration" ), m = 2 ), 2 , function (col_el ){
paste0(col_el , collapse = " vs. " )
}))
contrast_labels <- c(" Age (18-40 vs. ≥41)" , " Gender (female vs. male)" , " Coadministration (yes vs. no)" , " Vaccine (BNT162b2mRNA vs. mRNA-1273)" , " Smoking (yes vs. no)" , " Side effects (yes vs. no)" , risk_labels , coadmin_labels )
post_hoc_comp <- cbind(comparison = contrast_labels , post_hoc_comp )
post_hoc_comp %> % select(- contrast ) %> % knitr :: kable(row.names = F ) %> %
kableExtra :: kable_paper() %> %
kableExtra :: scroll_box(width = " 1000px" )
comparison
estimate
SE
df
t.ratio
p.value
p.adj
Age (18-40 vs. ≥41)
0.0323765
0.0165665
1207.2790
1.9543419
0.0508914
0.4132273
Gender (female vs. male)
0.0094272
0.0214004
1195.7206
0.4405171
0.6596423
1.0000000
Coadministration (yes vs. no)
-0.0736915
0.0207893
937.9455
-3.5446789
0.0004125
0.0066989
Vaccine (BNT162b2mRNA vs. mRNA-1273)
-0.1677947
0.0202995
669.0950
-8.2659418
0.0000000
0.0000000
Smoking (yes vs. no)
0.0422851
0.0242530
1090.4744
1.7434988
0.0815283
0.6018118
Side effects (yes vs. no)
0.0767238
0.0240995
865.4202
3.1836221
0.0015064
0.0203864
Be at Risk: False vs. Rather not true
-0.0425071
0.0196855
1192.5004
-2.1593099
0.1960676
1.0000000
Be at Risk: False vs. Partly
-0.0487488
0.0269748
1012.0775
-1.8071981
0.3698818
1.0000000
Be at Risk: False vs. Rather true
-0.0082020
0.0404317
1139.7984
-0.2028609
0.9996230
1.0000000
Be at Risk: False vs. True
0.0561754
0.0621585
730.0658
0.9037446
0.8954753
1.0000000
Be at Risk: Rather not true vs. Partly
-0.0062417
0.0296233
1037.7959
-0.2107028
0.9995618
1.0000000
Be at Risk: Rather not true vs. Rather true
0.0343051
0.0422529
1140.2403
0.8118992
0.9270240
1.0000000
Be at Risk: Rather not true vs. True
0.0986825
0.0632135
758.7685
1.5610994
0.5229647
1.0000000
Be at Risk: Partly vs. Rather true
0.0405468
0.0460440
1088.1065
0.8806106
0.9040751
1.0000000
Be at Risk: Partly vs. True
0.1049242
0.0658868
853.2955
1.5924930
0.5025926
1.0000000
Be at Risk: Rather true vs. True
0.0643774
0.0724842
958.4117
0.8881581
0.9013176
1.0000000
BNT162b2mRNA:Coadministration vs. mRNA-1273:Coadministration
-0.1677947
0.0202995
669.0950
-8.2659418
0.0000000
0.0000000
BNT162b2mRNA:Coadministration vs. BNT162b2mRNA:No Coadministration
-0.0736915
0.0207893
937.9455
-3.5446789
0.0023279
0.0236272
BNT162b2mRNA:Coadministration vs. mRNA-1273:No Coadministration
-0.2414862
0.0273508
1188.3990
-8.8292082
0.0000000
0.0000000
mRNA-1273:Coadministration vs. BNT162b2mRNA:No Coadministration
0.0941032
0.0306670
1187.2269
3.0685480
0.0117896
0.1063656
mRNA-1273:Coadministration vs. mRNA-1273:No Coadministration
-0.0736915
0.0207893
937.9455
-3.5446789
0.0023279
0.0236272
BNT162b2mRNA:No Coadministration vs. mRNA-1273:No Coadministration
-0.1677947
0.0202995
669.0950
-8.2659418
0.0000000
0.0000000
Table IgG concentrations and statistical significance
var_factors <- list (" AgeCategory" , " gender" , " coadmin" , " vaccine" , " smoking" , " risk" , " sideeffects" , c(" vaccine" ," coadmin" ))
gr_stat <- do.call(" rbind" , lapply(var_factors , function (var_fac ){
df_sum <- c()
if (length(var_fac ) == 1 ){
df_sum <- df_test %> % group_by(!! sym(var_fac )) %> % summarise(value = med_iqr(IgG ),
Min = min(IgG ),
Max = max(IgG ),
N = n()) %> %
rename(gr = !! sym(var_fac ))
}else {
df_sum <- df_test %> % group_by(vaccine , coadmin ) %> % summarise(value = med_iqr(IgG ),
Min = min(IgG ),
Max = max(IgG ),
N = n()) %> %
mutate(gr = paste0(vaccine , " " , coadmin )) %> % ungroup() %> % dplyr :: select(gr , value , Min , Max , N )
}
df_sum
}))
gr_mat <- do.call(" rbind" , strsplit(x = as.character(post_hoc_comp $ contrast ), split = " - " ))
colnames(gr_mat ) <- c(" gr1" , " gr2" )
df_table_igg <- cbind(post_hoc_comp , gr_mat ) %> % dplyr :: inner_join(gr_stat , by = c(" gr1" = " gr" )) %> % dplyr :: inner_join(gr_stat , by = c(" gr2" = " gr" )) %> %
mutate(p.short = dplyr :: case_when(p.value > = 0.01 ~ as.character(round(p.value , 2 )),
p.value < 0.0001 ~ " < 0.0001" ,
p.value < 0.001 ~ " < 0.001" ,
p.value < 0.01 ~ " < 0.01" ),
p.ad.short = dplyr :: case_when(p.adj > = 0.01 ~ as.character(round(p.adj , 2 )),
p.adj < 0.0001 ~ " < 0.0001" ,
p.adj < 0.001 ~ " < 0.001" ,
p.adj < 0.01 ~ " < 0.01" ),
across(.cols = where(is.numeric ), .fns = function (x ) format(round(x , digits = 2 ),
digits = 2 , nsmall = 2 ,
format = " f" , scientific = F )),
gr1 = if_else(grepl(x = comparison , pattern = " Side" ), true = " side effects" , false = gr1 ),
gr2 = if_else(grepl(x = comparison , pattern = " Side" ), true = " no side effects" , false = gr2 ))
df_table_igg <- df_table_igg %> % rename(p.adjusted = p.adj ,
" Median(Gr1) ± IQR" = value.x ,
" Median(Gr2) ± IQR" = value.y ,
" Min(Gr1)" = Min.x ,
" Min(Gr2)" = Min.y ,
" Max(Gr1)" = Max.x ,
" Max(Gr2)" = Max.y ,
" N(Gr1)" = N.x ,
" N(Gr2)" = N.y ,
" Group 1" = gr1 ,
" Group 2" = gr2 ) %> %
relocate(" Group 1" , " Group 2" , " N(Gr1)" , " Min(Gr1)" , " Max(Gr1)" , " Median(Gr1) ± IQR" , " N(Gr2)" , " Min(Gr2)" , " Max(Gr2)" , " Median(Gr2) ± IQR" , p.value , p.adjusted , p.short , p.ad.short ) %> %
dplyr :: select(- comparison , - contrast , - estimate , - SE , - df , - t.ratio )
df_table_igg %> % knitr :: kable() %> %
kableExtra :: kable_paper() %> %
kableExtra :: pack_rows(" Be at risk: " , 7 , 16 ) %> %
kableExtra :: pack_rows(" Vaccine third doses and Coadministration: " , 17 , 22 ) %> %
kableExtra :: add_header_above(c(" " = 2 , " Group 1 (IgG statistics)" = 4 , " Group 2 (IgG statistics)" = 4 , " Group 1 vs. Group 2" = 4 )) %> %
kableExtra :: scroll_box(width = " 1400px" )
Group 1
Group 2
N(Gr1)
Min(Gr1)
Max(Gr1)
Median(Gr1) ± IQR
N(Gr2)
Min(Gr2)
Max(Gr2)
Median(Gr2) ± IQR
p.value
p.adjusted
p.short
p.ad.short
18-40
40+
604.00
17.76
12985.14
2052.6 (1321.9-2979.5)
627.00
79.90
21287.91
1976.4 (1221.5-3172.6)
0.05
0.41
0.05
0.41
female
male
1015.00
79.54
21287.91
2024.4 (1287.3-3082.1)
216.00
17.76
13697.46
1980.8 (1157.2-3029.7)
0.66
1.00
0.66
1
Coadministration
No Coadministration
249.00
239.06
18541.53
1605 (1078-2504.7)
982.00
17.76
21287.91
2150.2 (1341.1-3242.3)
0.00
0.01
\< 0.001
\< 0.01
BNT162b2mRNA
mRNA-1273
996.00
17.76
13697.46
1888.4 (1192.6-2916.8)
235.00
365.36
21287.91
2655.8 (1698.7-3987.9)
0.00
0.00
\< 0.0001
\< 0.0001
smoker
non-smoker
150.00
204.73
12985.14
2134 (1437.2-3264.5)
1081.00
17.76
21287.91
1997.1 (1237.3-3051.2)
0.08
0.60
0.08
0.6
side effects
no side effects
1059.00
17.76
21287.91
2103.8 (1310.8-3184.6)
172.00
228.19
11950.47
1702.7 (1027.9-2534.7)
0.00
0.02
\< 0.01
0.02
Be at risk:
false
rather false
737.00
17.76
18189.57
1955.1 (1270.5-2935.4)
296.00
79.54
18541.53
2037.6 (1232.6-3238.8)
0.20
1.00
0.2
1
false
partly
737.00
17.76
18189.57
1955.1 (1270.5-2935.4)
124.00
244.08
21287.91
2258 (1339.7-3343.7)
0.37
1.00
0.37
1
false
rather true
737.00
17.76
18189.57
1955.1 (1270.5-2935.4)
51.00
128.32
12985.14
2396.9 (1377-3341.1)
1.00
1.00
1
1
false
true
737.00
17.76
18189.57
1955.1 (1270.5-2935.4)
23.00
79.90
6521.13
1493.7 (936.2-4202.1)
0.90
1.00
0.9
1
rather false
partly
296.00
79.54
18541.53
2037.6 (1232.6-3238.8)
124.00
244.08
21287.91
2258 (1339.7-3343.7)
1.00
1.00
1
1
rather false
rather true
296.00
79.54
18541.53
2037.6 (1232.6-3238.8)
51.00
128.32
12985.14
2396.9 (1377-3341.1)
0.93
1.00
0.93
1
rather false
true
296.00
79.54
18541.53
2037.6 (1232.6-3238.8)
23.00
79.90
6521.13
1493.7 (936.2-4202.1)
0.52
1.00
0.52
1
partly
rather true
124.00
244.08
21287.91
2258 (1339.7-3343.7)
51.00
128.32
12985.14
2396.9 (1377-3341.1)
0.90
1.00
0.9
1
partly
true
124.00
244.08
21287.91
2258 (1339.7-3343.7)
23.00
79.90
6521.13
1493.7 (936.2-4202.1)
0.50
1.00
0.5
1
rather true
true
51.00
128.32
12985.14
2396.9 (1377-3341.1)
23.00
79.90
6521.13
1493.7 (936.2-4202.1)
0.90
1.00
0.9
1
Vaccine third doses and Coadministration:
BNT162b2mRNA Coadministration
mRNA-1273 Coadministration
225.00
239.06
8923.95
1560.7 (1078-2493.6)
24.00
547.41
18541.53
1891.1 (1068.2-3324)
0.00
0.00
\< 0.0001
\< 0.0001
BNT162b2mRNA Coadministration
BNT162b2mRNA No Coadministration
225.00
239.06
8923.95
1560.7 (1078-2493.6)
771.00
17.76
13697.46
1955.1 (1234.6-3022.9)
0.00
0.02
\< 0.01
0.02
BNT162b2mRNA Coadministration
mRNA-1273 No Coadministration
225.00
239.06
8923.95
1560.7 (1078-2493.6)
211.00
365.36
21287.91
2709.8 (1735.4-4001.2)
0.00
0.00
\< 0.0001
\< 0.0001
mRNA-1273 Coadministration
BNT162b2mRNA No Coadministration
24.00
547.41
18541.53
1891.1 (1068.2-3324)
771.00
17.76
13697.46
1955.1 (1234.6-3022.9)
0.01
0.11
0.01
0.11
mRNA-1273 Coadministration
mRNA-1273 No Coadministration
24.00
547.41
18541.53
1891.1 (1068.2-3324)
211.00
365.36
21287.91
2709.8 (1735.4-4001.2)
0.00
0.02
\< 0.01
0.02
BNT162b2mRNA No Coadministration
mRNA-1273 No Coadministration
771.00
17.76
13697.46
1955.1 (1234.6-3022.9)
211.00
365.36
21287.91
2709.8 (1735.4-4001.2)
0.00
0.00
\< 0.0001
\< 0.0001
Coefficients pairwise comparisons (All)
post_hoc_comp <- post_hoc_comp [rev(seq_len(nrow(post_hoc_comp ))),]
post_hoc_comp $ comparison <- factor (post_hoc_comp $ comparison , levels = post_hoc_comp $ comparison )
post_hoc_comp %> % ggplot2 :: ggplot() +
ggplot2 :: geom_point(ggplot2 :: aes(y = comparison , x = estimate )) +
ggplot2 :: geom_errorbar(aes(y = comparison , xmin = estimate - SE , xmax = estimate + SE ), width = .2 ,
position = position_dodge(.9 )) +
ggplot2 :: theme_bw() +
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 12 , colour = " black" ),
axis.title = ggplot2 :: element_text(face = " bold" , size = 12 ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 12 ),
legend.position = " bottom" ) +
ggplot2 :: xlab(" Effect on IgG (estimated coefficient difference)" ) +
ggplot2 :: ylab(" Comparison" )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " png" , " Regression_model_mean_se_estimates.png" ), device = " png" , width = 10 , height = 12 , dpi = 300 )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " svg" , " Regression_model_mean_se_estimates.svg" ), device = " svg" , width = 10 , height = 12 , dpi = 300 )
Comparison IgG titres based on vaccination concept
# Coadmin
gr_matrix <- as.data.frame(t(combn(levels(df_test $ coadmin ), 2 )))
colnames(gr_matrix ) <- c(" group1" , " group2" )
gr_count <- df_test %> % group_by(coadmin ) %> % count()
stat.comp <- gr_matrix %> % full_join(gr_count , by = c(" group1" = " coadmin" ), suffix = c(" 1" , " 2" )) %> %
inner_join(gr_count , by = c(" group2" = " coadmin" ), suffix = c(" 1" , " 2" )) %> %
mutate(contrast = paste0(group1 , " - " , group2 )) %> %
inner_join(post_hoc_comp %> % select(contrast , p.value , p.adj )) %> % mutate(" .y." = " IgG" )
stat.comp <- stat.comp %> % rstatix :: add_significance() %> % filter(p.adj < 0.05 ) %> % rstatix :: add_x_position()
box_upper <- df_test %> % group_by(coadmin ) %> % summarise(igg_max = quantile(x = 10 ^ logIgG , probs = 0.995 ))
stat.comp <- stat.comp %> % inner_join(box_upper , by = c(" group1" = " coadmin" )) %> % rename(ygr1 = igg_max ) %> % inner_join(box_upper , by = c(" group2" = " coadmin" )) %> % rename(ygr2 = igg_max )
stat.comp <- stat.comp %> % group_by(group1 , group2 ) %> %
mutate(diff_comp = xmax - xmin ,
ymax = round(log10(max(ygr1 , ygr2 )), 2 )) %> %
arrange(diff_comp , ymax ) %> % group_by(diff_comp , ymax ) %> %
mutate(id = cur_group_id()) %> % as.data.frame()
# Vaccine + Coadmin
gr_matrix <- as.data.frame(t(combn(x = c(" BNT162b2mRNA Coadministration" , " mRNA-1273 Coadministration" , " BNT162b2mRNA No Coadministration" , " mRNA-1273 No Coadministration" ), m = 2 )))
colnames(gr_matrix ) <- c(" group1" , " group2" )
gr_count <- df_test %> % mutate(`vaccine:coadmin` = paste0(vaccine ," " , coadmin )) %> % group_by(`vaccine:coadmin` ) %> % count()
stat.comp <- gr_matrix %> % full_join(gr_count , by = c(" group1" = " vaccine:coadmin" ), suffix = c(" 1" , " 2" )) %> %
inner_join(gr_count , by = c(" group2" = " vaccine:coadmin" ), suffix = c(" 1" , " 2" )) %> %
mutate(contrast = paste0(group1 , " - " , group2 )) %> %
inner_join(post_hoc_comp %> % select(contrast , p.value , p.adj )) %> % mutate(" .y." = " IgG" )
stat.comp <- stat.comp %> % rstatix :: add_significance() %> % filter(p.adj < 0.05 ) %> % rstatix :: add_x_position()
box_upper <- df_test %> % mutate(`vaccine:coadmin` = paste0(vaccine ," " , coadmin )) %> % group_by(`vaccine:coadmin` ) %> % summarise(igg_max = quantile(x = 10 ^ logIgG , probs = 0.995 ))
stat.comp <- stat.comp %> % inner_join(box_upper , by = c(" group1" = " vaccine:coadmin" )) %> % rename(ygr1 = igg_max ) %> % inner_join(box_upper , by = c(" group2" = " vaccine:coadmin" )) %> % rename(ygr2 = igg_max )
stat.comp <- stat.comp %> % group_by(group1 , group2 ) %> %
mutate(diff_comp = xmax - xmin ,
ymax = round(log10(max(ygr1 , ygr2 )), 2 )) %> %
arrange(diff_comp , ymax ) %> % group_by(diff_comp , ymax ) %> %
mutate(id = cur_group_id()) %> % as.data.frame()
stat.comp <- stat.comp %> % mutate(xmin = case_when(xmin < = 2 ~ 0.8 + (xmin - 1 ) * 0.4 ,
xmin > 2 ~ 1 + (xmin - 1 ) * 0.4 ),
xmax = case_when(xmax < = 2 ~ 0.8 + (xmax - 1 ) * 0.4 ,
xmax > 2 ~ 1 + (xmax - 1 ) * 0.4 ))
bx_plt <- df_test %> % mutate(`vaccine:coadmin` = paste0(vaccine ," " , coadmin )) %> %
ggplot2 :: ggplot(ggplot2 :: aes(x = vaccine , y = 10 ^ logIgG , fill = `vaccine:coadmin` )) +
ggplot2 :: stat_boxplot(geom = " errorbar" , lwd = 1 , show.legend = FALSE , width = 0.4 , position = position_dodge(width = 0.8 )) +
ggplot2 :: geom_boxplot(aes(x = vaccine , y = 10 ^ logIgG , fill = `vaccine:coadmin` ), width = 0.8 , color = " black" , lwd = 1 , show.legend = FALSE , outlier.size = 0 ) +
ggbeeswarm :: geom_quasirandom(dodge.width = .75 , alpha = 0.8 , pch = 20 , size = 0.5 ) +
ggplot2 :: theme_bw() +
ggplot2 :: scale_fill_manual(labels = rep(c(" Coadministration" , " No Coadministration" ), times = 2 ), values = c(" #42B540FF" , " darkgreen" , " #ED0000FF" , " darkred" )) +
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 17 , colour = " black" ),
axis.title = ggplot2 :: element_text(face = " bold" , size = 16 ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 16 ),
legend.position = " bottom" ) +
ggplot2 :: ylab(" Anti-SARS-CoV-2-Spike IgG [BAU/ml]" ) +
ggplot2 :: scale_y_log10(limits = c(10 , 70000 ), breaks = 10 ^ (0 : 4 ), labels = format(10 ^ (0 : 4 ), scientific = F )) +
ggplot2 :: annotation_logticks(sides = " l" ) +
ggplot2 :: xlab(" " ) +
# ggplot2::geom_hline(yintercept = 31.5, lty = 2) +
ggsignif :: geom_signif(xmin = stat.comp $ xmin ,
xmax = stat.comp $ xmax ,
y_position = 0.1 * 1.4 ^ (seq_along(stat.comp $ ymax )) + (stat.comp $ ymax ),
annotation = stat.comp $ p.adj.signif ,
tip_length = 0.01 , vjust = 0.75 , lwd = 0.75 , textsize = 7 ) +
ggplot2 :: guides(fill = ggplot2 :: guide_legend(override.aes = list (shape = 22 , size = 8 , stroke = 1 ), ncol = 2 ))
bx_plt
ggplot2 :: ggsave(plot = bx_plt , filename = file.path(plot.dir , " png" , " Boxplot_coadministration_comparison.png" ), device = " png" , width = 8 , height = 6 , dpi = 300 )
ggplot2 :: ggsave(plot = bx_plt , filename = file.path(plot.dir , " svg" , " Boxplot_coadministration_comparison.svg" ), device = " svg" , width = 8 , height = 6 , dpi = 300 )
Comparison influential factors
plot_vars <- c(" AgeCategory" , " gender" , " smoking" , " sideeffects" , " risk" )
tick_labels <- list (Age = c(" 18-40" , " 41+" ),
Gender = c(" female" , " male" ),
Smoking = c(" smoker" , " non-smoker" ),
" Side effects" = c(" yes" , " no" ),
" Be at Risk" = c(" False" , " Rather not true " , " Partly" , " Rather true" , " True" )
)
plot_list <- list ()
for (i in seq_along(plot_vars )){
gr_matrix <- as.data.frame(t(combn(levels(df_test [[plot_vars [i ]]]), 2 )))
colnames(gr_matrix ) <- c(" group1" , " group2" )
gr_count <- df_test %> % group_by(!! sym(plot_vars [i ])) %> % count()
stat.comp <- gr_matrix %> % full_join(gr_count , by = c(" group1" = plot_vars [i ]), suffix = c(" 1" , " 2" )) %> %
inner_join(gr_count , by = c(" group2" = plot_vars [i ]), suffix = c(" 1" , " 2" )) %> %
mutate(contrast = paste0(group1 , " - " , group2 )) %> %
inner_join(post_hoc_comp %> % select(comparison , contrast , p.value , p.adj ) %> % filter(grepl(pattern = names(tick_labels )[i ], x = comparison ))) %> % mutate(" .y." = " IgG" )
stat.comp <- stat.comp %> % rstatix :: add_significance() %> % filter(p.adj < 0.05 ) %> % rstatix :: add_x_position()
box_upper <- df_test %> % group_by(!! sym(plot_vars [i ])) %> % summarise(igg_max = quantile(x = IgG , probs = 0.995 ))
stat.comp <- stat.comp %> % inner_join(box_upper , by = c(" group1" = plot_vars [i ])) %> % rename(ygr1 = igg_max ) %> %
inner_join(box_upper , by = c(" group2" = plot_vars [i ])) %> % rename(ygr2 = igg_max )
stat.comp <- stat.comp %> % group_by(group1 , group2 ) %> %
mutate(diff_comp = xmax - xmin ,
ymax = round(log10(max(ygr1 , ygr2 )), 2 )) %> %
arrange(diff_comp , ymax ) %> % group_by(diff_comp , ymax ) %> %
mutate(id = cur_group_id()) %> % as.data.frame()
cat(' ### Comparison: ' , unique(as.character(stat.comp $ comparison )), ' \n ' )
bx_plt <- df_test %> % ggplot2 :: ggplot(ggplot2 :: aes_string(x = plot_vars [i ], y = " IgG" )) +
ggplot2 :: stat_boxplot(geom = " errorbar" , lwd = 1 , width = 0.5 , show.legend = FALSE ) +
ggplot2 :: geom_boxplot(aes_string(fill = plot_vars [i ]), color = " black" , lwd = 1 , show.legend = FALSE , outlier.size = 0 ) +
ggbeeswarm :: geom_quasirandom(alpha = 0.8 , width = 0.4 , pch = 20 , size = 0.5 ) +
ggplot2 :: scale_y_log10() +
ggplot2 :: theme_bw() +
ggsci :: scale_fill_lancet() +
ggplot2 :: scale_x_discrete(labels = tick_labels [[i ]])+
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 14 , colour = " black" ),
axis.title = ggplot2 :: element_text(face = " bold" , size = 12 ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 12 ),
legend.position = " none" ) +
ggplot2 :: xlab(names(tick_labels )[i ]) +
ggplot2 :: ylab(" Anti-SARS-CoV-2-Spike IgG [BAU/ml]" ) +
ggplot2 :: annotation_logticks(sides = " l" )
# ggplot2::geom_hline(yintercept = 31.5, lty = 2)
if (dim(stat.comp )[1 ] > 0 ){
box_upper <- df_test %> % group_by(!! sym(plot_vars [i ])) %> % summarise(igg_max = quantile(x = IgG , probs = 0.995 ))
if (df_test %> % pull(!! sym(plot_vars [i ])) %> % unique() %> % length() > 2 ){
stat.comp <- stat.comp %> % group_by(group1 , group2 ) %> %
mutate(diff_comp = xmax - xmin ,
ymax = round(log10(max(ygr1 , ygr2 )), 2 ),
p_val = p.adj.signif ) %> %
arrange(diff_comp , ymax ) %> % group_by(diff_comp , ymax ) %> %
mutate(id = cur_group_id()) %> % as.data.frame()
}else {
stat.comp <- stat.comp %> % group_by(group1 , group2 ) %> %
mutate(diff_comp = xmax - xmin ,
ymax = round(log10(max(ygr1 , ygr2 )), 2 ),
p_val = p.adj.signif ) %> %
arrange(diff_comp , ymax ) %> % group_by(diff_comp , ymax ) %> %
mutate(id = cur_group_id()) %> % as.data.frame()
}
bx_plt <- bx_plt + ggsignif :: geom_signif(xmin = stat.comp $ group1 ,
xmax = stat.comp $ group2 ,
y_position = 0.175 * seq_along(stat.comp $ ymax ) + (stat.comp $ ymax ),
annotation = stat.comp $ p.adj.signif ,
tip_length = 0.01 , vjust = 0.75 , lwd = 0.75 , textsize = 7 )
}
plot_list [[i ]] <- bx_plt
}
# # Generate combined plot for confounding factors associated to IgG titres
plot_list [[1 ]] <- plot_list [[1 ]] +
ggplot2 :: xlab(" " ) +
ggsci :: scale_fill_jco() +
ggplot2 :: facet_wrap(~ . , labeller = ggplot2 :: as_labeller(c(`(all)` = " Age [Years]" ))) +
ggplot2 :: theme(axis.title.x = ggplot2 :: element_blank(),
strip.text = ggplot2 :: element_text(size = 14 , face = " bold" ),
strip.background = ggplot2 :: element_rect(fill = " white" ))
plot_list [[2 ]] <- plot_list [[2 ]] +
ggplot2 :: xlab(" " ) +
ggplot2 :: facet_wrap(~ . , labeller = ggplot2 :: as_labeller(c(`(all)` = " Gender" ))) +
ggplot2 :: theme(axis.title = ggplot2 :: element_blank(),
strip.text = ggplot2 :: element_text(size = 14 , face = " bold" ),
strip.background = ggplot2 :: element_rect(fill = " white" ))
plot_list [[3 ]] <- plot_list [[3 ]] +
ggplot2 :: xlab(" " ) +
ggsci :: scale_fill_jama() +
ggplot2 :: facet_wrap(~ . , labeller = ggplot2 :: as_labeller(c(`(all)` = " Smoking" ))) +
ggplot2 :: theme(axis.title = ggplot2 :: element_blank(),
strip.text = ggplot2 :: element_text(size = 14 , face = " bold" ),
strip.background = ggplot2 :: element_rect(fill = " white" ))
plot_list [[4 ]] <- plot_list [[4 ]] +
ggplot2 :: xlab(" " ) +
ggsci :: scale_fill_lancet() +
ggplot2 :: facet_wrap(~ . , labeller = ggplot2 :: as_labeller(c(`(all)` = " Side effects" ))) +
ggplot2 :: theme(axis.title = ggplot2 :: element_blank(),
strip.text = ggplot2 :: element_text(size = 14 , face = " bold" ),
strip.background = ggplot2 :: element_rect(fill = " white" ))
plot_list [[5 ]] <- plot_list [[5 ]] +
ggplot2 :: xlab(" " ) +
ggsci :: scale_fill_jco() +
ggplot2 :: facet_wrap(~ . , labeller = ggplot2 :: as_labeller(c(`(all)` = " Be at Risk" ))) +
ggplot2 :: theme(axis.title.x = ggplot2 :: element_blank(),
strip.text = ggplot2 :: element_text(size = 14 , face = " bold" ),
strip.background = ggplot2 :: element_rect(fill = " white" ))
comb_plt_top <- cowplot :: plot_grid(plotlist = plot_list [1 : 3 ], ncol = 3 , rel_widths = c(0.31 , 0.3 , 0.3 ), labels = LETTERS [1 : 3 ], label_size = 16 )
comb_plt_bottom <- cowplot :: plot_grid(plotlist = plot_list [5 : 4 ], ncol = 2 , rel_widths = c(0.61 , 0.3 ), labels = LETTERS [4 : 5 ], label_size = 16 )
comb_plt <- cowplot :: plot_grid(comb_plt_top , comb_plt_bottom , nrow = 2 , ncol = 1 )
comb_plt
ggplot2 :: ggsave(plot = comb_plt , filename = file.path(plot.dir , " png" , " Boxplot_other_categorical_factors.png" ), device = " png" , width = 12 , height = 8 , dpi = 300 )
ggplot2 :: ggsave(plot = comb_plt , filename = file.path(plot.dir , " png/Combined_boxplotsl.png" ),
device = " png" , width = 12 , height = 8 , dpi = 300 )
ggplot2 :: ggsave(plot = comb_plt , filename = file.path(plot.dir , " svg" , " Boxplot_other_categorical_factors.svg" ), device = " svg" , width = 12 , height = 8 , dpi = 300 )
ggplot2 :: ggsave(plot = comb_plt , filename = file.path(plot.dir , " svg/Combined_boxplotsl.svg" ),
device = " svg" , width = 12 , height = 8 , dpi = 300 )
Days between vaccination and serum sampling
pred_int <- predict(gls_mod , interval = " prediction" )
pred_time_igg <- cbind(df_test %> % select(logIgG , time_serum_coadmin ), Prediction = pred_int )
y_hat_igg <- predict(gls_mod , interval = " prediction" )
rsquare_cv <- cor(df_test $ logIgG , y_hat_igg )^ 2
cor_time_igg <- round(cor(df_test $ time_serum_coadmin , df_test $ logIgG , method = " spearman" ), 2 )
line_plt_time <- df_test %> %
ggplot2 :: ggplot(ggplot2 :: aes(x = time_serum_coadmin , y = IgG )) +
ggplot2 :: geom_point(size = 1 , alpha = 0.75 ) +
ggplot2 :: scale_y_log10(limits = c(10 , 30000 ), expand = c(0 ,0 )) +
ggplot2 :: geom_smooth(data = pred_time_igg , ggplot2 :: aes(x = time_serum_coadmin , y = 10 ^ Prediction ), method = " lm" ) +
ggsci :: scale_color_lancet() +
ggplot2 :: scale_x_continuous(breaks = seq(0 ,90 ,15 ), labels = seq(0 ,90 ,15 )) +
ggplot2 :: theme_bw() +
ggplot2 :: theme(axis.text = ggplot2 :: element_text(size = 14 , colour = " black" ),
axis.title = ggplot2 :: element_text(face = " bold" , size = 12 ),
legend.title = ggplot2 :: element_blank(),
legend.text = ggplot2 :: element_text(size = 16 ),
legend.position = " bottom" ) +
ggplot2 :: xlab(" Days since vaccination" ) +
ggplot2 :: ylab(" Anti-SARS-CoV-2-Spike IgG [BAU/ml]" ) +
ggplot2 :: annotation_logticks(sides = " l" ) +
ggplot2 :: annotate(geom = " text" , label = paste0(" italic(c)== " , cor_time_igg ), x = 50 , y = 10000 , cex = 5 , parse = TRUE , hjust = 0 ) +
ggplot2 :: annotate(geom = " text" , label = paste0(" italic(p) " , anova_gls $ p_plot [7 ]), x = 50 , y = 13000 , cex = 5 , parse = TRUE , hjust = 0 )
line_plt_time
ggplot2 :: ggsave(plot = line_plt_time , filename = file.path(plot.dir , " png/Scatterplot_time_serum.png" ),
device = " png" , width = 8 , height = 6 , dpi = 300 )
ggplot2 :: ggsave(plot = line_plt_time , filename = file.path(plot.dir , " svg/Scatterplot_time_serum.svg" ),
device = " svg" , width = 8 , height = 6 , dpi = 300 )
Coadministration irrespective of vaccination
Table: Fisher test results
fisher_tests_coad <- fisher_tests_gr(df = df_coad , gr1 = " coadmin" , var_expr = " se[1-6]" )
p.adj_fisher_tests_coad <- cbind(fisher_tests_coad [,- c(9 ,10 )], " p.adjusted" = round(p.adjust(fisher_tests_coad $ p.value , " BY" ), 2 ))
knitr :: kable(p.adj_fisher_tests_coad , align = " c" ) %> %
kableExtra :: kable_styling(full_width = F , position = " left" )%> %
kableExtra :: column_spec(1 , bold = T ) %> %
kableExtra :: collapse_rows(columns = 4 : 9 , valign = " middle" )
group1
group2
gr2.1
gr2.2
estimate
p.value
conf.low
conf.high
p.adjusted
Coadministration
se1
149
100
0.9126640
0.5596714
0.6806514
1.2269668
1.00
No Coadministration
se1
609
373
Coadministration
se2
93
156
0.7814688
0.0984122
0.5798145
1.0493465
0.92
No Coadministration
se2
425
557
Coadministration
se3
85
164
0.7232706
0.0300151
0.5334901
0.9758017
0.56
No Coadministration
se3
410
572
Coadministration
se4
65
184
0.8430940
0.3090158
0.6053320
1.1642561
1.00
No Coadministration
se4
290
692
Coadministration
se5
119
130
0.8234485
0.1778373
0.6169598
1.0982951
No Coadministration
se5
517
465
Coadministration
se6
32
217
0.8311161
0.4222212
0.5330110
1.2651649
No Coadministration
se6
148
834
fisher_plot_odds(fisher_test_df = fisher_tests_coad , ylab_add = " coadministration" )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " png/Side_effects_OR_only_coadmin.png" ),
device = " png" , width = 8 , height = 6 , dpi = 300 )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " svg/Side_effects_OR_only_coadmin.svg" ),
device = " svg" , width = 8 , height = 6 , dpi = 300 )
BarPlot - Pairwise Comparisons
barplot_sideeffects_percentage(p.adj_fisher_tests_df = p.adj_fisher_tests_coad )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " png/Side_effects_Barplot_percentage_only_coadmin.png" ),
device = " png" , width = 8 , height = 6 , dpi = 300 )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " svg/Side_effects_Barplot_percentage_only_coadmin.svg" ),
device = " svg" , width = 8 , height = 6 , dpi = 300 )
Coadministration regarding different COVID-19 vaccines
Table: Fisher test results
fisher_tests_sep <- sapply(levels(df_coad $ vaccine ), function (vacc_name ){
fisher_tests_gr(df = df_coad %> % filter(vaccine %in% vacc_name ), gr1 = " coadmin" , var_expr = " se[1-6]" )
}, simplify = F )
df_vacc_sep <- data.frame (super_group = rep(levels(df_coad $ vaccine ), each = dim(fisher_tests_sep [[1 ]])[1 ]), do.call(" rbind" , fisher_tests_sep ))
df_vacc_sep_p_adj <- cbind(df_vacc_sep , " p.adjusted" = round(p.adjust(df_vacc_sep $ p.value , " BY" ), 2 ))
knitr :: kable(df_vacc_sep_p_adj [,- c(1 ,10 ,11 )], align = " l" , row.names = F ) %> %
kableExtra :: collapse_rows(columns = 6 : 9 ) %> %
kableExtra :: pack_rows(" BNT162b2mRNA" , 1 , 12 ) %> %
kableExtra :: pack_rows(" mRNA-1273" , 13 , 24 ) %> %
kableExtra :: kable_styling(full_width = F , position = " left" )%> %
kableExtra :: column_spec(1 , bold = T )
group1
group2
gr2.1
gr2.2
estimate
p.value
conf.low
conf.high
p.adjusted
BNT162b2mRNA
Coadministration
se1
137
88
0.9862146
0.9381564
0.7199510
1.355247
1
No Coadministration
se1
472
299
0.9862146
Coadministration
se2
82
143
0.8437421
0.3138048
0.6118310
1.158685
No Coadministration
se2
312
459
0.8437421
Coadministration
se3
75
150
0.7641390
0.1014027
0.5505391
1.054709
No Coadministration
se3
305
466
0.7641390
Coadministration
se4
52
173
0.8084375
0.2626709
0.5586435
1.156728
No Coadministration
se4
209
562
0.8084375
Coadministration
se5
105
120
0.8593869
0.3255030
0.6307151
1.169750
No Coadministration
se5
389
382
0.8593869
Coadministration
se6
26
199
0.7937022
0.3759011
0.4821740
1.267975
No Coadministration
se6
109
662
0.7937022
mRNA-1273
Coadministration
se1
12
12
0.5416226
0.1807878
0.2107962
1.390668
No Coadministration
se1
137
74
0.5416226
Coadministration
se2
11
13
0.7348089
0.5220536
0.2838994
1.868655
No Coadministration
se2
113
98
0.7348089
Coadministration
se3
10
14
0.7220896
0.5214102
0.2737143
1.837775
No Coadministration
se3
105
106
0.7220896
Coadministration
se4
13
11
1.8914402
0.1861765
0.7420222
4.908946
No Coadministration
se4
81
130
1.8914402
Coadministration
se5
14
10
0.9081904
0.8288735
0.3559063
2.400739
No Coadministration
se5
128
83
0.9081904
Coadministration
se6
6
18
1.4674462
0.4200744
0.4470834
4.188326
No Coadministration
se6
39
172
1.4674462
fisher_plot_odds(fisher_test_df = df_vacc_sep , ylab_add = " coadministration" , wrap = T )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " png/Side_effects_OR_coadmin_by_vaccine.png" ),
device = " png" , width = 8 , height = 8 , dpi = 300 )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " svg/Side_effects_OR_coadmin_by_vaccine.svg" ),
device = " svg" , width = 8 , height = 8 , dpi = 300 )
BarPlot - Pairwise Comparisons
barplot_sideeffects_percentage(p.adj_fisher_tests_df = df_vacc_sep_p_adj , wrap = T )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " png/Side_effects_Barplot_percentage_coadmin_by_vaccine.png" ),
device = " png" , width = 8 , height = 8 , dpi = 300 )
ggplot2 :: ggsave(plot = last_plot(), filename = file.path(plot.dir , " svg/Side_effects_Barplot_percentage_coadmin_by_vaccine.svg" ),
device = " svg" , width = 8 , height = 8 , dpi = 300 )