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

