简体   繁体   中英

Correctly place geom_text labels in forest plot with "fill" parameter in ggplot2

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?

I've also asked the RStudio community for help on March 9, 2022. Here is a link to the original post.

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 an error bar for the confidence intervals
  geom_errorbar(aes(xmin = conf.low, xmax = conf.high), position = position_dodge(.9), size = 1) +
        
        ## add in labels     
  geom_text(aes( label = paste0(estimate, " (", ci, ") n = ", n_obs), x = estimate, y = term),color = "black", position = position_dodge(.9), show.legend = FALSE, check_overlap = FALSE) +

  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")

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

You need to add a grouping variable to the text layer, since you remove its dodging variable by specifying color = 'black' outside aes .

Also, you can use vjust to move the text above the bars:

data %>% rowwise() %>%
  ggplot(aes(x = estimate, y = term, color = group), alpha = .7, width = .7) +
  geom_point(position = position_dodge(.9), size = 1.5) +
  geom_errorbar(aes(xmin = conf.low, xmax = conf.high), 
                position = position_dodge(.9), size = 1) +  
  geom_text(aes( label = paste0(estimate, " (", ci, ") n = ", n_obs), 
                 x = estimate, y = term, group = group), color = "black", 
            position = position_dodge(0.9), vjust = -0.4,
            show.legend = FALSE, check_overlap = FALSE) +
  ggplot2::theme_bw() +
  scale_colour_grey() +
  geom_vline(xintercept = 1, linetype = "dashed") +
  ylab("") +
  xlab("") +
  theme(legend.position = "top")

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM