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