rggplot2gridextrar-forestplot

Manual Forest plot in ggplot, how to tune variable titles?


I am trying to build a forest plot with the results of some meta-analysis (performed by myself, so I do not want to use the meta package). The results you can copy for reproducibility are those:

structure(list(
cohort = c("cohort1", "cohort2", "cohort3", "cohort4", "cohort5", "cohort6", "cohort7"), 
beta = c(-0.238927428673765, -0.015095974676985, 0.364330350386939, -0.111741616010383, -0.196697525708519, -0.019993786083488, 0.0530815000660616), 
IC95_low = c(-0.339291563342713, -0.0857064739555255, -0.0365912072567037, -0.505483167285389, -0.472341750731663, -0.369903598485953, -0.147466346165432), 
IC95_high = c(-0.138563294004818, 0.0555145246015554, 0.765251908030581, 0.281999935264622, 0.0789466993146241, 0.329916026318977, 0.253629346297556), 
n = c(6199L, 531L, 109L, 452L, 529L, 826L, 924L), 
age = c(8.6, 2.5, 8.5, 7.8, 5.8, 4.2, 6.9)), 
row.names = c(NA, -7L), class = "data.frame")

I already have achieved those results with the following code with ggplot2 and gridExtra:

forest = result %>%
    ggplot(aes(y = cohort, x = beta)) +
    geom_point(aes(size = n), shape = 18) +
    geom_errorbarh(aes(xmin = IC95_low, xmax = IC95_high), height = 0.15) +
    geom_vline(xintercept = 0, color = "red", linetype = "dashed", cex = 0.7, alpha = 0.5) +
    labs(x = "mbmi beta", y = "") +
    theme(axis.text.y=element_blank(),
          axis.ticks.y=element_blank(),
          legend.position = "none"
    ) +
    scale_size_continuous(range = c(2,6))
  
  data_table <- ggplot(data = result, aes(y = cohort)) +
    geom_text(aes(x = 0, label = cohort), hjust = 0) +
    geom_text(aes(x = 0.7, label = n)) +
    geom_text(aes(x = 1, label = age), hjust = 1) +
    scale_colour_identity() +
    theme_void() + 
    theme(plot.margin = margin(5, 0, 35, 0))
  
  grid.arrange(data_table, forest, ncol = 2, widths = c(1,3),
               top = textGrob(paste("Results from available cohorts in:", outcome),gp=gpar(fontsize=20,font=4)))

enter image description here

However, I would like to put the name variables from the table structure on the left with COHORT, n, and mean_age... It feels impossible and I don't know which should have to be the proper way to do it so.

Any ideas we can discuss?


Solution

  • One option would be to add your header of column labels as axis text or labels. Additionally I switched to patchwork to glue your plots as IMHO it makes a fairly good job when it comes to aligning plots:

    library(ggplot2)
    library(patchwork)
    outcome <- "gc"
    
    forest <- result |>
      ggplot(aes(y = cohort, x = beta)) +
      geom_point(aes(size = n), shape = 18) +
      geom_errorbarh(aes(xmin = IC95_low, xmax = IC95_high), height = 0.15) +
      geom_vline(xintercept = 0, color = "red", linetype = "dashed", cex = 0.7, alpha = 0.5) +
      labs(x = "mbmi beta", y = "") +
      theme(
        axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        legend.position = "none",
        plot.title = element_text(size = 24, face = "bold.italic")
      ) +
      scale_size_continuous(range = c(2, 6)) +
      labs(title = paste0("Results from available cohorts in: ", outcome))
    
    data_table <- ggplot(data = result, aes(y = cohort)) +
      geom_text(aes(x = 0, label = cohort), hjust = 0) +
      geom_text(aes(x = 0.7, label = n)) +
      geom_text(aes(x = 1, label = age), hjust = 1) +
      scale_x_continuous(position = "top", breaks = c(0, .7, 1), labels = c("Cohort", "n", "age")) +
      scale_colour_identity() +
      theme_void() +
      theme(axis.text.x = element_text(hjust = c(0, .5, 1), face = "bold"))
    
    data_table + forest & 
      plot_layout(ncol = 2, widths = c(1, 3))
    

    enter image description here