Hi There,
I want to create annotated publication-ready forest plots comparing different models. How do I ensure that the labels are placed above and tight against the corresponding error bars and do not overlap?
Thank you for your help!
Here is what I tried:
library(tidyverse)
#> Warning: package 'tibble' was built under R version 4.1.2
#> Warning: package 'tidyr' was built under R version 4.1.2
#> Warning: package 'readr' was built under R version 4.1.2
#> Warning: package 'dplyr' was built under R version 4.1.2
library(knitr)
#> Warning: package 'knitr' was built under R version 4.1.2
data <- tibble::tribble(
~term, ~n_obs, ~estimate, ~conf.low, ~conf.high, ~ci, ~p.value, ~group,
"A", 101L, 0.62, 0.497390282, 0.797429694, "0.50 to 0.80", 0.000123131, "One",
"A", 65L, 0.57, 0.468908017, 0.693458768, "0.47 to 0.69", 1.83138e-08, "Two",
"A", 36L, 0.81, 0.623804568, 1.064787867, "0.62 to 1.06", 0.133680272, "Three",
"B", 26L, 0.87, 0.665400224, 1.1489204, "0.67 to 1.15", 0.335220534, "One",
"B", 16L, 1.02, 0.755403541, 1.388386542, "0.76 to 1.39", 0.878076678, "Two",
"B", 10L, 0.29, 0.091804704, 0.978289216, "0.09 to 0.98", 0.045898245, "Three",
"C", 143L, 0.90, 0.749027775, 1.089930323, "0.75 to 1.09", 0.289131987, "One",
"C", 82L, 1.02, 0.82229374, 1.286815562, "0.82 to 1.29", 0.804649191, "Two",
"C", 61L, 0.61, 0.359730119, 1.036462037, "0.36 to 1.04", 0.06765433, "Three"
)
data %>% kable()
| term |
n_obs |
estimate |
conf.low |
conf.high |
ci |
p.value |
group |
| A |
101 |
0.62 |
0.4973903 |
0.7974297 |
0.50 to 0.80 |
0.0001231 |
One |
| A |
65 |
0.57 |
0.4689080 |
0.6934588 |
0.47 to 0.69 |
0.0000000 |
Two |
| A |
36 |
0.81 |
0.6238046 |
1.0647879 |
0.62 to 1.06 |
0.1336803 |
Three |
| B |
26 |
0.87 |
0.6654002 |
1.1489204 |
0.67 to 1.15 |
0.3352205 |
One |
| B |
16 |
1.02 |
0.7554035 |
1.3883865 |
0.76 to 1.39 |
0.8780767 |
Two |
| B |
10 |
0.29 |
0.0918047 |
0.9782892 |
0.09 to 0.98 |
0.0458982 |
Three |
| C |
143 |
0.90 |
0.7490278 |
1.0899303 |
0.75 to 1.09 |
0.2891320 |
One |
| C |
82 |
1.02 |
0.8222937 |
1.2868156 |
0.82 to 1.29 |
0.8046492 |
Two |
| C |
61 |
0.61 |
0.3597301 |
1.0364620 |
0.36 to 1.04 |
0.0676543 |
Three |
data %>% rowwise() %>%
## plot with variable on the y axis and estimate (OR) on the x axis
ggplot(aes(x = estimate, y = term, color = group), alpha = .7, width = .7) +
## show the estimate as a point
geom_point(position = position_dodge(.9), size = 1.5) +
## add in labels
geom_text(aes(color = "black", label = paste0(estimate, " (", ci, ") n = ", n_obs)), position = position_dodge(1.9), show.legend = FALSE, check_overlap = FALSE) +
## add in an error bar for the confidence intervals
geom_errorbar(aes(xmin = conf.low, xmax = conf.high), position = position_dodge(.9), size = 1) +
ggplot2::theme_bw() +
scale_colour_grey() +
## show where OR = 1 is for reference as a dashed line
geom_vline(xintercept = 1, linetype = "dashed") +
ylab("") +
xlab("") +
theme(legend.position = "top")
#> Warning: position_dodge requires non-overlapping x intervals

Created on 2022-03-09 by the reprex package (v2.0.1)