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)