Search code examples
rr-forestplot

Add multiple text blocks left and right of ggplot


I would like to modify the following forest plot:

library(ggplot2)
library(dplyr)

set.seed(123)

mydata <- data.frame(
  subgroup = c("age < 60", "age > 60", "male", "female"),
  n =      c(76, 37, 55, 58), 
  HR =      c(-2.12, 2.88, -0.91, 3.83), 
  CIlower = c(-5.64, 0.48, -2.78, 2.57), 
  CIupper = c(-0.37, 4.38, 0.47, 4.28), 
  pvalue =  c(0.083, 0.438, 0.237, 0.683))

mydata %>%
ggplot(aes(x = subgroup, y = HR, ymin = CIlower, ymax = CIupper)) +
    geom_pointrange() +
    geom_hline(yintercept = 1, lty = 2) +
    xlab("group") + 
    ylab("HR") +
    coord_flip() +
    theme_light() +
    theme(plot.margin = unit(c(1, 4, 1, 1), "lines")) +
  
  
  annotate("text", x = 4, y = 4, label = mydata$pvalue[4])
  annotate("text", x = 3, y = 4, label = mydata$pvalue[3])
  annotate("text", x = 2, y = 4, label = mydata$pvalue[2])
  annotate("text", x = 1, y = 4, label = mydata$pvalue[1])

My attempt with annotate was only possible within my plot.

My plan is to add text that is relevant for the plot left or right of the plot area. I would like to place text with the count of the subgroup observation (stored in the variable "n" of mydata) and the HR with CI as well as the p-value (stored in the correspoding variables in mydata) right of the plot in line with the group and the data point. I know that this could be done with labels (https://newbedev.com/ggplot2-annotate-outside-of-plot, first code solution) - this works great with one label because the text is positioned according to the data points, but I have more than one label (n, HR/CI + p-value). The third solution with grid did not work for me as the y position differed when I enlarged the plot in my markdown (or I simply did something wrong).

Can anyone help me?

Thank you!


Solution

  • Do you want something like this?

    ggplot(data = mtcars, aes(x = wt, y = mpg)) + 
        geom_point() +
        theme(plot.margin = unit(c(1,3,1,1), "cm")) + 
        annotate("text", x = 7.7, y = 10, label = "text1") +
        annotate("text", x = 8, y = 5, label = "text2") +
        annotate("text", x = 8.5, y = 20, label = "text3") +
        coord_cartesian(xlim = c(0,7), ylim = c(0, 35), clip = "off") #without this you can't print text labels outside the plot
    

    enter image description here