| Title: | Publication-Ready Forest Plots |
|---|---|
| Description: | Creates publication-ready forest plots from any tabular data containing point estimates and confidence intervals. Suitable for visualising results from regression models, meta-analyses, subgroup analyses, or any comparative study. Supports group and subgroup headings, summary estimates displayed as diamonds, grouped estimates with automatic colour and shape mapping, vertical dodging of multiple estimates within the same row, customisable text columns alongside the plot, and optional row striping. Provides a helper to export plots to PDF, PNG, SVG, or TIFF. Built on 'tinyplot' for clean, consistent visual styling with a minimal dependency footprint. |
| Authors: | Lorenzo Fabbri [aut, cre, cph] |
| Maintainer: | Lorenzo Fabbri <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.3.0.9000 |
| Built: | 2026-06-02 06:59:50 UTC |
| Source: | https://github.com/lorenzofabbri/forrest |
Draws a publication-ready forest plot from a data frame. Each row represents one estimate — a study, a predictor, a model, a subgroup, or any other unit of analysis.
forrest( data, estimate, lower, upper, label = NULL, group = NULL, is_summary = NULL, weight = NULL, section = NULL, subsection = NULL, section_indent = TRUE, section_spacer = TRUE, section_cols = NULL, subsection_cols = NULL, ref_label = FALSE, ref_line = 0, log_scale = FALSE, xlim = NULL, xlab = "Estimate (95% CI)", title = NULL, header = NULL, cols = NULL, widths = NULL, stripe = FALSE, dodge = FALSE, pch = 15, shape = NULL, lwd = 2, cex = 1, col = NULL, cols_by_group = FALSE, legend_pos = "topright", legend_shape_pos = "bottomright", theme = "default", ... )forrest( data, estimate, lower, upper, label = NULL, group = NULL, is_summary = NULL, weight = NULL, section = NULL, subsection = NULL, section_indent = TRUE, section_spacer = TRUE, section_cols = NULL, subsection_cols = NULL, ref_label = FALSE, ref_line = 0, log_scale = FALSE, xlim = NULL, xlab = "Estimate (95% CI)", title = NULL, header = NULL, cols = NULL, widths = NULL, stripe = FALSE, dodge = FALSE, pch = 15, shape = NULL, lwd = 2, cex = 1, col = NULL, cols_by_group = FALSE, legend_pos = "topright", legend_shape_pos = "bottomright", theme = "default", ... )
data |
A data frame, tibble, or data.table. |
estimate |
Column name (string) for point estimates. |
lower |
Column name (string) for lower confidence interval bounds. |
upper |
Column name (string) for upper confidence interval bounds. |
label |
Column name (string) for row labels displayed on the y-axis or
in the left text panel. If |
group |
Column name (string) for a grouping variable. Rows that share a group value receive the same colour, and a legend is drawn automatically. |
is_summary |
Column name (string) of a logical vector. Rows where this
is |
weight |
Column name (string) of numeric row weights. When provided,
point size scales as |
section |
Column name (string) for a grouping variable that determines
section structure. Whenever the value of this column changes (run-length
boundary), a bold section header row is automatically inserted before the
group. Row order is preserved; no automatic sorting is applied. See also
|
subsection |
Column name (string) for a second-level grouping variable.
Requires |
section_indent |
Logical. If |
section_spacer |
Logical. If |
section_cols |
Named character vector. Names must be a subset of the
names of |
subsection_cols |
Like |
ref_label |
Logical. When |
ref_line |
Numeric. Position of the vertical reference line (e.g. |
log_scale |
Logical. If |
xlim |
Numeric vector of length 2 giving x-axis limits. Computed from
the data when |
xlab |
Label for the x-axis. Default is |
title |
Plot title. Default is |
header |
Optional header string placed above the label column. When
|
cols |
Named character vector specifying extra text columns to display
to the right of the plot. Names become column headers; values are column
names in |
widths |
Numeric vector of relative panel widths. When |
stripe |
Logical. If |
dodge |
Logical or positive numeric. When |
pch |
Point character for non-summary rows. Default is |
shape |
Column name (string) for a shape variable. When provided,
different values of the column are rendered with different point characters
and a shape legend is drawn. Use together with |
lwd |
Line width for confidence interval whiskers. Default is |
cex |
Point size multiplier. Default is |
col |
Colour or character vector of colours. When |
cols_by_group |
Logical. Relevant only when |
legend_pos |
Position of the colour legend when |
legend_shape_pos |
Position of the shape legend when |
theme |
Visual theme name ( |
... |
Graphical parameters forwarded to the internal tinyplot call
(e.g. |
Rows with NA estimates are treated as reference-category rows: they produce
no point or confidence interval, and their label is rendered in regular
(non-bold) font. To create section headers and spacers automatically, use
the section (and optionally subsection) arguments instead of inserting
NA rows by hand.
Invisibly returns NULL. Called for its side effect of producing a
plot.
# Basic forest plot: linear model coefficients dat <- data.frame( predictor = c("Age (per 10 y)", "Female sex", "BMI (per 5 kg/m\u00b2)", "Current smoker"), estimate = c(0.42, -0.38, 0.19, -0.31), lower = c(0.22, -0.56, -0.02, -0.51), upper = c(0.62, -0.20, 0.40, -0.11) ) forrest(dat, estimate = "estimate", lower = "lower", upper = "upper", label = "predictor", xlab = "Regression coefficient (95% CI)" ) # Section headers from a grouping column dat2 <- data.frame( domain = c("Lifestyle", "Lifestyle", "Clinical", "Clinical"), predictor = c("Physical activity", "Diet quality", "BMI (per 5 kg/m\u00b2)", "Systolic BP (per 10 mmHg)"), estimate = c(-0.31, -0.18, 0.19, 0.25), lower = c(-0.51, -0.36, -0.02, 0.08), upper = c(-0.11, -0.00, 0.40, 0.42) ) forrest(dat2, estimate = "estimate", lower = "lower", upper = "upper", label = "predictor", section = "domain", xlab = "Regression coefficient (95% CI)" )# Basic forest plot: linear model coefficients dat <- data.frame( predictor = c("Age (per 10 y)", "Female sex", "BMI (per 5 kg/m\u00b2)", "Current smoker"), estimate = c(0.42, -0.38, 0.19, -0.31), lower = c(0.22, -0.56, -0.02, -0.51), upper = c(0.62, -0.20, 0.40, -0.11) ) forrest(dat, estimate = "estimate", lower = "lower", upper = "upper", label = "predictor", xlab = "Regression coefficient (95% CI)" ) # Section headers from a grouping column dat2 <- data.frame( domain = c("Lifestyle", "Lifestyle", "Clinical", "Clinical"), predictor = c("Physical activity", "Diet quality", "BMI (per 5 kg/m\u00b2)", "Systolic BP (per 10 mmHg)"), estimate = c(-0.31, -0.18, 0.19, 0.25), lower = c(-0.51, -0.36, -0.02, 0.08), upper = c(-0.11, -0.00, 0.40, 0.42) ) forrest(dat2, estimate = "estimate", lower = "lower", upper = "upper", label = "predictor", section = "domain", xlab = "Regression coefficient (95% CI)" )
Writes the plot produced by forrest() (or any base-R plotting code) to a
file. The graphics device is inferred from the file extension.
save_forrest(file, plot, width = 7, height = 5, dpi = 300, bg = "white")save_forrest(file, plot, width = 7, height = 5, dpi = 300, bg = "white")
file |
Output file path. Supported extensions: |
plot |
A zero-argument function whose body calls |
width |
Plot width in inches. Default |
height |
Plot height in inches. Default |
dpi |
Resolution in dots per inch for raster formats ( |
bg |
Background colour. Default |
Invisibly returns file.
dat <- data.frame( label = c("Age (per 10 y)", "Female sex", "Current smoker"), estimate = c(0.42, -0.38, -0.31), lower = c(0.22, -0.56, -0.51), upper = c(0.62, -0.20, -0.11) ) tmp <- tempfile(fileext = ".pdf") save_forrest(tmp, function() { forrest( dat, estimate = "estimate", lower = "lower", upper = "upper", label = "label", xlab = "Regression coefficient (95% CI)" ) })dat <- data.frame( label = c("Age (per 10 y)", "Female sex", "Current smoker"), estimate = c(0.42, -0.38, -0.31), lower = c(0.22, -0.56, -0.51), upper = c(0.62, -0.20, -0.11) ) tmp <- tempfile(fileext = ".pdf") save_forrest(tmp, function() { forrest( dat, estimate = "estimate", lower = "lower", upper = "upper", label = "label", xlab = "Regression coefficient (95% CI)" ) })