The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Getting started with ggmeta

ggmeta turns a meta-analysis into a publication-quality forest plot built on ggplot2. It works two ways:

Because the result is an ordinary ggplot, you keep the full ggplot2 toolbox: themes, scales, annotations, and saving with ggsave().

library(ggmeta)
library(ggplot2)

A forest plot from a meta object

Fit a meta-analysis as usual, then hand it to ggforest():

library(meta)

m <- metabin(
  event.e = c(14, 30, 15, 22), n.e = c(100, 150, 100, 120),
  event.c = c(10, 25, 12, 18), n.c = c(100, 150, 100, 120),
  studlab = c("Study A", "Study B", "Study C", "Study D"),
  sm = "RR"
)

ggforest(m)

ggforest() does the sensible thing automatically: it draws study confidence intervals with weight-proportional squares, the common- and random-effects summary diamonds, a prediction interval, a null-effect reference line, a log x-axis for ratio measures, and a heterogeneity caption.

Standalone: a tidy data frame

You don’t need the meta package. Any data frame with studlab, estimate, ci_lower, and ci_upper works:

df <- data.frame(
  studlab  = c("Trial 1", "Trial 2", "Trial 3", "Trial 4"),
  estimate = c(0.82, 0.91, 0.68, 1.05),
  ci_lower = c(0.61, 0.74, 0.48, 0.80),
  ci_upper = c(1.10, 1.12, 0.96, 1.38)
)

ggforest(df, null_effect = 1)

On-the-fly meta-analysis

Give ggforest() a se column (or let it recover the standard error from the confidence interval) and set add_summary = TRUE to pool the studies with an inverse-variance common-effect and a DerSimonian–Laird random-effects model — without the meta package:

studies <- data.frame(
  studlab  = c("Trial 1", "Trial 2", "Trial 3", "Trial 4", "Trial 5"),
  estimate = c(0.10, 0.35, 0.22, 0.48, 0.05),
  se       = c(0.12, 0.10, 0.14, 0.16, 0.11)
)
studies$ci_lower <- studies$estimate - 1.96 * studies$se
studies$ci_upper <- studies$estimate + 1.96 * studies$se

ggforest(studies, add_summary = TRUE)

A meta::forest()-style column table

Set columns = TRUE to add the familiar effect / 95% CI / weight columns with headers to the right of the plot (use effect_header to name the estimate column, and pass a subset like columns = c("estimate", "ci") if you prefer):

ggforest(studies, add_summary = TRUE, columns = TRUE, effect_header = "SMD")

Custom text columns

For a column of your own — sample sizes, events, anything — use geom_forest_text(), which aligns to the study rows through the shared y. format_effect() builds an “estimate (CI)” label. Widen the panel with expand_limits() to make room:

studies$n <- c(120, 240, 150, 180, 110)

ggforest(studies, add_summary = TRUE) +
  geom_forest_text(aes(y = studlab, label = n), data = studies,
                   x = -0.35, hjust = 0.5) +
  expand_limits(x = -0.45)

Journal styles

Layout presets adapt a plot to common journal conventions. They are ordinary ggplot2 components, so you add them with +:

p <- ggforest(df, null_effect = 1)
layout_jama(p)

layout_bmj() and layout_revman5() are also available, and because the plot is a ggplot you can keep customising with theme(), labs(), and friends.

Other effect measures

ggforest() back-transforms every summary measure correctly — exponentiation for ratios, inverse-logit for logit proportions, Fisher’s z for correlations, and so on. Single-group proportions and rates get no (meaningless) reference line:

prop <- metaprop(
  event = c(15, 20, 12, 25), n = c(50, 60, 55, 70),
  studlab = paste("Cohort", 1:4), sm = "PLOGIT"
)
ggforest(prop)

Saving

ggforest() returns a ggplot, so save it like any other:

p <- ggforest(df, null_effect = 1)
ggsave("forest.png", p, width = 7, height = 4, dpi = 300)

Where to next

See vignette("from-meta-forest") for a side-by-side comparison with meta::forest() and tips on reproducing its output.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.