Package {ggforestplotR}


Title: Publication-Ready Forest Plots with 'ggplot2'
Version: 0.3.0
Description: Transform model coefficients into flexible forest plots using 'ggplot2'. Provides helpers to standardize coefficient data from a range of modelling workflows and render publication-ready forest plots with a consistent interface.
License: MIT + file LICENSE
Encoding: UTF-8
Imports: ggplot2, patchwork, rlang
Suggests: broom, broom.mixed, dplyr, knitr, lme4, rmarkdown, survival, testthat (≥ 3.0.0), tibble
VignetteBuilder: knitr
Config/testthat/edition: 3
Config/Needs/website: pkgdown
URL: https://thatoneguy006.github.io/ggforestplotR/, https://github.com/thatoneguy006/ggforestplotR
BugReports: https://github.com/thatoneguy006/ggforestplotR/issues
Config/roxygen2/version: 8.0.0
NeedsCompilation: no
Packaged: 2026-07-07 20:55:42 UTC; Carso
Author: Carson Richardson [aut, cre, cph]
Maintainer: Carson Richardson <carson.richardson@outlook.com>
Repository: CRAN
Date/Publication: 2026-07-07 21:10:02 UTC

ggforestplotR: Forest plots from model coefficients with ggplot2

Description

Transform model coefficients into flexible forest plots using ggplot2. Provides helpers to standardize coefficient data from a range of modelling workflows and render publication-ready coefficient plots with a consistent interface.

Author(s)

Maintainer: Carson Richardson carson.richardson@outlook.com [copyright holder]

Authors:

See Also

Useful links:


Add a summary table to a forest plot

Description

Compose a summary table onto a forest plot.

Usage

add_forest_table(
  plot = NULL,
  position = c("left", "right"),
  columns = NULL,
  term_header = "Term",
  n_header = "N",
  events_header = "Events",
  estimate_label = NULL,
  p_header = "P-value",
  column_labels = NULL,
  digits = NULL,
  estimate_digits = NULL,
  interval_digits = NULL,
  p_digits = NULL,
  estimate_fmt = NULL,
  ci_fmt = NULL,
  text_size = NULL,
  header_text_size = NULL,
  header_fontface = "bold",
  header_family = NULL,
  striped_rows = NULL,
  stripe_fill = NULL,
  stripe_colour = NULL,
  stripe_alpha = NULL,
  grid_lines = FALSE,
  grid_line_colour = "black",
  grid_line_size = 0.3,
  grid_line_linetype = 1
)

Arguments

plot

A plot created by ggforestplot(). Leave as NULL to use + add_forest_table(...) syntax.

position

Whether to place the table on the left or right of the forest plot.

columns

Optional explicit columns to display in the side table, in the order they should appear. Accepts built-in names such as "term", "n", "events", "estimate", "ci", and "p", arbitrary original dataframe columns, or numeric positions in the supplied data. "conf.low" and "conf.high" are accepted as aliases for "ci".

term_header

Header text for the term column.

n_header

Header text for the N column.

events_header

Header text for the Events column.

estimate_label

Header label for the estimate column. Defaults to the model-derived label when available.

p_header

Header text for the p-value column.

column_labels

Optional named vector used to relabel table column headers. Names should match values supplied to columns after column resolution, such as "term", "estimate", "ci", "p", or an arbitrary original dataframe column.

digits

Deprecated. Number of digits used when formatting estimates and p-values. Defaults to 2. Use estimate_digits, interval_digits, and p_digits for separate control.

estimate_digits

Number of digits used for point estimates.

interval_digits

Number of digits used for confidence interval bounds.

p_digits

Number of digits used for p-values.

estimate_fmt

Format string for the estimate column. Use {estimate}, {conf.low}, and {conf.high} as placeholders. The shorthand ⁠{conf.low, conf.high}⁠ is also supported. Defaults to "{estimate} ({conf.low}, {conf.high})", or "{estimate}" when columns includes "ci".

ci_fmt

Format string for the confidence interval column when columns includes "ci". Use {conf.low} and {conf.high} as placeholders. The shorthand ⁠{conf.low, conf.high}⁠ is also supported. Defaults to "({conf.low}, {conf.high})".

text_size

Text size for table contents. Defaults to 3.2.

header_text_size

Header text size for table column labels. Defaults to 11.

header_fontface

Font face used for table column labels. Defaults to "bold".

header_family

Optional font family used for table column labels.

striped_rows

Whether to draw alternating row stripes behind the table. Defaults to the stripe setting used in ggforestplot().

stripe_fill

Fill colour used for striped rows. Defaults to the stripe fill used in ggforestplot().

stripe_colour

Outline colour for striped rows. Defaults to the stripe outline used in ggforestplot().

stripe_alpha

Transparency for striped rows. Defaults to the stripe alpha used in ggforestplot().

grid_lines

Whether to draw black horizontal grid lines in the table.

grid_line_colour

Colour used for the table grid lines.

grid_line_size

Line width used for the table grid lines.

grid_line_linetype

Line type used for the table grid lines.

Value

A patchwork-composed plot containing the forest plot and side table, or a ggplot add-on object when plot = NULL.

Examples

coefs <- data.frame(
  term = c("Age", "BMI", "Treatment"),
  estimate = c(0.3, -0.2, 0.4),
  conf.low = c(0.1, -0.4, 0.2),
  conf.high = c(0.5, 0.0, 0.6),
  sample_size = c(120, 115, 98),
  p_value = c(0.012, 0.031, 0.004)
)

p <- ggforestplot(coefs, n = "sample_size", p.value = "p_value")
add_forest_table(
  p,
  position = "left",
  columns = c("term", "n", "estimate", "p"),
  estimate_label = "Beta"
)

ggforestplot(coefs, n = "sample_size", p.value = "p_value") +
  add_forest_table(
    position = "right",
    columns = c("term", "n", "estimate", "p"),
    estimate_label = "Beta"
  )

Add split tables around a forest plot

Description

Compose split table blocks around a forest plot so that summary data appear on both sides of the plotting panel.

Usage

add_split_table(
  plot = NULL,
  left_columns = NULL,
  right_columns = NULL,
  term_header = "Term",
  n_header = "N",
  events_header = "Events",
  estimate_label = NULL,
  p_header = "P-value",
  column_labels = NULL,
  digits = NULL,
  estimate_digits = NULL,
  interval_digits = NULL,
  p_digits = NULL,
  estimate_fmt = NULL,
  ci_fmt = NULL,
  text_size = NULL,
  header_text_size = NULL,
  header_fontface = "bold",
  header_family = NULL,
  striped_rows = NULL,
  stripe_fill = NULL,
  stripe_colour = NULL,
  stripe_alpha = NULL,
  left_width = NULL,
  plot_width = NULL,
  right_width = NULL
)

Arguments

plot

A plot created by ggforestplot(). Leave as NULL to use + add_split_table(...) syntax.

left_columns

Optional explicit columns to place on the left side of the forest plot. Accepts built-in names such as "term", "n", "events", "estimate", "ci", and "p", arbitrary original dataframe columns, or numeric positions in the supplied data. "conf.low" and "conf.high" are accepted as aliases for "ci".

right_columns

Optional explicit columns to place on the right side of the forest plot. Accepts built-in names such as "estimate", "ci", and "p", arbitrary original dataframe columns, or numeric positions in the supplied data. "conf.low" and "conf.high" are accepted as aliases for "ci".

term_header

Header text for the term column.

n_header

Header text for the N column.

events_header

Header text for the Events column.

estimate_label

Header label for the estimate column. Defaults to the model-derived label when available.

p_header

Header text for the p-value column.

column_labels

Optional named vector used to relabel table column headers. Names should match values supplied to left_columns or right_columns after column resolution, such as "term", "estimate", "ci", "p", or an arbitrary original dataframe column.

digits

Deprecated. Number of digits used when formatting estimates and p-values. Defaults to 2. Use estimate_digits, interval_digits, and p_digits for separate control.

estimate_digits

Number of digits used for point estimates.

interval_digits

Number of digits used for confidence interval bounds.

p_digits

Number of digits used for p-values.

estimate_fmt

Format string for the estimate column. Use {estimate}, {conf.low}, and {conf.high} as placeholders. The shorthand ⁠{conf.low, conf.high}⁠ is also supported. Defaults to "{estimate} ({conf.low}, {conf.high})", or "{estimate}" when table columns include "ci".

ci_fmt

Format string for the confidence interval column when table columns include "ci". Use {conf.low} and {conf.high} as placeholders. The shorthand ⁠{conf.low, conf.high}⁠ is also supported. Defaults to "({conf.low}, {conf.high})".

text_size

Text size for table contents. Defaults to 3.2.

header_text_size

Header text size for table column labels. Defaults to 11.

header_fontface

Font face used for table column labels. Defaults to "bold".

header_family

Optional font family used for table column labels.

striped_rows

Whether to draw alternating row stripes behind the split table layout. Defaults to the stripe setting used in ggforestplot().

stripe_fill

Fill colour used for striped rows. Defaults to the stripe fill used in ggforestplot().

stripe_colour

Outline colour for striped rows. Defaults to the stripe outline used in ggforestplot().

stripe_alpha

Transparency for striped rows. Defaults to the stripe alpha used in ggforestplot().

left_width

Optional width allocated to the left table block. By default this is derived from the number of displayed left-side columns relative to plot_width.

plot_width

Optional width allocated to the forest plot panel. Defaults to 2.5.

right_width

Optional width allocated to the right table block. By default this is derived from the number of displayed right-side columns relative to plot_width.

Value

A patchwork-composed plot containing a left table, the forest plot, and a right table, or a ggplot add-on object when plot = NULL.

Examples

coefs <- data.frame(
  term = c("Age", "BMI", "Treatment"),
  estimate = c(0.3, -0.2, 0.4),
  conf.low = c(0.1, -0.4, 0.2),
  conf.high = c(0.5, 0.0, 0.6),
  sample_size = c(120, 115, 98),
  p_value = c(0.012, 0.031, 0.004)
)

p <- ggforestplot(coefs, n = "sample_size", p.value = "p_value")
add_split_table(
  p,
  left_columns = c("term", "n"),
  right_columns = c("estimate", "p"),
  estimate_label = "HR"
)

ggforestplot(coefs, n = "sample_size", p.value = "p_value") +
  add_split_table(
    left_columns = c(1, 5),
    right_columns = c(2, 6),
    estimate_label = "HR"
  )

Standardize coefficient data for forest plots

Description

Standardizes a coefficient table into the internal forest-plot data structure used throughout ggforestplotR.

Usage

as_forest_data(
  data,
  term,
  estimate,
  conf.low,
  conf.high,
  label = term,
  term_labels = NULL,
  group = NULL,
  grouping = NULL,
  separate_groups = NULL,
  n = NULL,
  events = NULL,
  p.value = NULL,
  exponentiate = FALSE,
  sort_terms = c("none", "descending", "ascending")
)

Arguments

data

A data frame containing coefficient estimates and intervals.

term

Column name holding the model term identifier.

estimate

Column name holding the point estimate.

conf.low

Column name holding the lower confidence bound.

conf.high

Column name holding the upper confidence bound.

label

Optional column name used for the displayed row label.

term_labels

Optional named vector used to relabel displayed terms. Names should match values in the term column and values are the labels to display.

group

Optional column name used for color-grouping multiple estimates per row.

grouping

Optional column name used to split rows into grouped plot sections.

separate_groups

Optional column name used to identify labeled variable blocks that can be outlined with separator lines.

n

Optional column name holding sample sizes or other N labels for table helpers.

events

Optional column name holding event counts or event labels for table helpers.

p.value

Optional column name holding p-values.

exponentiate

Logical; if TRUE, require positive values for estimates and intervals.

sort_terms

How to sort rows: "none", "descending", or "ascending".

Value

A standardized data frame ready for ggforestplot() and the table composition helpers. Original dataframe columns are retained for table helpers so they can be displayed with add_forest_table(columns = ...).

Examples

raw <- data.frame(
  variable = c("Age", "BMI", "Treatment"),
  beta = c(0.10, -0.08, 0.34),
  lower = c(0.02, -0.16, 0.12),
  upper = c(0.18, 0.00, 0.56)
)

as_forest_data(
  data = raw,
  term = "variable",
  estimate = "beta",
  conf.low = "lower",
  conf.high = "upper"
)

Bind multiple model summaries for a grouped forest plot

Description

Tidies multiple fitted models and stacks their fixed-effect coefficient tables into a single forest-plot data frame. The resulting data can be passed directly to ggforestplot(), where model labels are used as the grouping variable for dodged, color-coded estimates.

Usage

bind_forest_models(models, model_labels = NULL, exponentiate = NULL, ...)

Arguments

models

A non-empty list of fitted model objects supported by tidy_forest_model().

model_labels

Optional labels used to identify each model in the forest plot. Defaults to list names when present, otherwise "Model 1", "Model 2", and so on.

exponentiate

NULL, a single logical value, or one logical value per model. NULL uses the canonical scale inferred by tidy_forest_model() for each model.

...

Additional arguments passed to tidy_forest_model(), such as conf.level, intercept, term_labels, or sort_terms.

Value

A standardized forest-plot data frame with one row per model term and a group column containing the model labels.

Examples

if (requireNamespace("broom", quietly = TRUE)) {
  fit1 <- lm(mpg ~ wt + hp, data = mtcars)
  fit2 <- lm(mpg ~ wt + qsec, data = mtcars)

  bound <- bind_forest_models(
    list(Base = fit1, Adjusted = fit2)
  )

  ggforestplot(bound)
}

Draw a ggplot2 forest plot

Description

Builds a forest plot from standardized coefficient data or directly from a fitted model.

Usage

ggforestplot(
  data,
  term = "term",
  estimate = "estimate",
  conf.low = "conf.low",
  conf.high = "conf.high",
  label = term,
  term_labels = NULL,
  group = NULL,
  facet = NULL,
  facet_strip_position = c("left", "right"),
  grouping = NULL,
  grouping_strip_position = NULL,
  separate_groups = NULL,
  n = NULL,
  events = NULL,
  p.value = NULL,
  exponentiate = NULL,
  sort_terms = c("none", "descending", "ascending"),
  point_size = 2.3,
  point_shape = 19,
  linewidth = 0.5,
  line_size = NULL,
  staple_width = 0.2,
  ci_limits = NULL,
  ci_arrows = TRUE,
  ci_arrow_length = 0.08,
  ci_arrow_type = c("closed", "open"),
  dodge_width = 0.6,
  separate_lines = FALSE,
  separator_line_linetype = 2,
  separator_line_colour = "black",
  separator_line_size = 0.4,
  striped_rows = FALSE,
  stripe_fill = "grey95",
  stripe_colour = NA,
  stripe_alpha = 1,
  ref_line = NULL,
  ref_label = NULL,
  ref_linetype = 2,
  ref_color = "grey60"
)

Arguments

data

Either a tidy coefficient data frame or a model object supported by broom::tidy().

term

Column name holding the model term identifiers.

estimate

Column name holding the point estimates.

conf.low

Column name holding the lower confidence bounds.

conf.high

Column name holding the upper confidence bounds.

label

Optional column name used for the displayed row labels.

term_labels

Optional named vector used to relabel displayed terms. Names should match values in the term column and values are the labels to display.

group

Optional column name used for color-grouping estimates.

facet

Optional column name used to split rows into faceted plot sections. If this column is a factor, its levels control facet order.

facet_strip_position

Positioning for facet strip labels.

grouping

Deprecated. Use facet instead.

grouping_strip_position

Deprecated. Use facet_strip_position instead.

separate_groups

Optional column name used to identify labeled variable blocks that can be outlined with grid lines.

n

Optional column name holding sample sizes or other N labels for table helpers.

events

Optional column name holding event counts or event labels for table helpers.

p.value

Optional column name holding p-values.

exponentiate

Logical; if TRUE, transform the estimates and draw the axis on the log scale with the reference line at 1. For model objects, NULL uses the canonical scale when it can be inferred, such as hazard ratios for Cox models.

sort_terms

How to sort rows: "none", "descending", or "ascending".

point_size

Point size for coefficient markers.

point_shape

Shape used for coefficient markers.

linewidth

Line width for confidence intervals.

line_size

Deprecated. Use linewidth instead.

staple_width

Width of the terminal staples on confidence interval lines.

ci_limits

Optional numeric vector of length 2 used to truncate displayed confidence intervals. Intervals extending beyond these limits are clipped to the boundary and marked with arrows when ci_arrows is TRUE.

ci_arrows

Logical; if TRUE, draw outward-facing arrows for confidence intervals truncated by ci_limits.

ci_arrow_length

Length of CI truncation arrows in inches.

ci_arrow_type

Arrowhead type for truncated confidence intervals. Passed to grid::arrow().

dodge_width

Horizontal dodging used for grouped estimates.

separate_lines

Logical; if TRUE, draw grid lines around each labeled block identified by separate_groups.

separator_line_linetype

Line type used for separator lines.

separator_line_colour

Colour used for separator lines.

separator_line_size

Line width used for separator lines.

striped_rows

Logical; if TRUE, shade alternating rows.

stripe_fill

Fill color used for shaded rows.

stripe_colour

Border color for shaded rows.

stripe_alpha

Transparency for shaded rows.

ref_line

Numeric x-value where the reference line is drawn, or NULL to hide it. When omitted, defaults to 0 for additive effects and 1 for exponentiated effects.

ref_label

Optional label drawn alongside the reference line.

ref_linetype

Line type for the reference line.

ref_color

Color for the reference line.

Value

A ggplot object. Use standard ggplot2 functions such as ggplot2::labs() for plot labels, and add composition helpers after styling the main plot.

Examples

coefs <- data.frame(
  term = c("Age", "BMI", "Treatment"),
  estimate = c(0.10, -0.08, 0.34),
  conf.low = c(0.02, -0.16, 0.12),
  conf.high = c(0.18, 0.00, 0.56)
)

ggforestplot(coefs)

ggforestplot(coefs, striped_rows = TRUE, point_shape = 17)

Tidy a model object for forest plotting

Description

Uses broom::tidy() to convert a fitted model into forest-plot data. Mixed models are supported through broom.mixed tidy methods when that package is installed.

Usage

tidy_forest_model(
  model,
  conf.int = TRUE,
  conf.level = 0.95,
  exponentiate = NULL,
  intercept = FALSE,
  term_labels = NULL,
  sort_terms = c("none", "descending", "ascending")
)

Arguments

model

A fitted model object supported by broom::tidy() or, for mixed models, a broom.mixed tidy method.

conf.int

Logical; if TRUE, request confidence intervals from broom::tidy().

conf.level

Confidence level for intervals.

exponentiate

Logical; passed through to broom::tidy().

intercept

Logical; if FALSE, drop the intercept term.

term_labels

Optional named vector used to relabel displayed terms. Names should match model term names and values are the labels to display.

sort_terms

How to sort rows: "none", "descending", or "ascending".

Value

A standardized coefficient data frame ready for ggforestplot().

Examples

if (requireNamespace("broom", quietly = TRUE)) {
  fit <- lm(mpg ~ wt + hp + qsec, data = mtcars)
  tidy_forest_model(fit)

  set.seed(123)
  logit_data <- data.frame(
    age = rnorm(250, mean = 62, sd = 8),
    bmi = rnorm(250, mean = 28, sd = 4),
    treatment = factor(rbinom(250, 1, 0.45), labels = c("Control", "Treatment"))
  )
  linpred <- -9 + 0.09 * logit_data$age + 0.11 * logit_data$bmi +
    0.9 * (logit_data$treatment == "Treatment")
  logit_data$event <- rbinom(250, 1, plogis(linpred))
  logit_fit <- glm(event ~ age + bmi + treatment, data = logit_data, family = binomial())

  tidy_forest_model(logit_fit, exponentiate = TRUE)
}