Split forest plots create separate plots for each value of a categorical variable, with an interactive sidebar for navigation. This is ideal for subgroup analyses where you want to compare results across different populations.

TipWhen to Use Split vs Group
Feature Use When
split_by Many subgroups (5+), each deserves focused attention
group Few subgroups (2-4), want to see all at once

Split creates a sidebar with one plot per subgroup. Group creates collapsible sections in a single plot.

Basic Split

Use split_by to create separate plots for each unique value:

Code
set.seed(42)
trial_data <- data.frame(
  study = paste0("Study ", 1:30),
  region = sample(c("North America", "Europe", "Asia Pacific"), 30, replace = TRUE),
  or = exp(rnorm(30, log(0.8), 0.3)),
  lower = NA, upper = NA
)
trial_data$lower <- trial_data$or * exp(-1.96 * 0.25)
trial_data$upper <- trial_data$or * exp(1.96 * 0.25)

forest_plot(trial_data,
  point = "or", lower = "lower", upper = "upper",
  label = "study",
  split_by = "region",
  scale = "log", null_value = 1,
  axis_label = "Odds Ratio (95% CI)",
  title = "Treatment Effect by Region"
)

The floating sidebar shows each region. Click to navigate between subgroups.

Hierarchical Splits

Split by multiple variables for nested navigation:

Code
set.seed(123)
n <- 50
subgroup_data <- data.frame(
  study = paste0("Study ", sprintf("%02d", 1:n)),
  sex = sample(c("Male", "Female"), n, replace = TRUE),
  age_group = sample(c("18-40", "41-65", "65+"), n, replace = TRUE),
  or = exp(rnorm(n, log(0.75), 0.25)),
  lower = NA, upper = NA
)
subgroup_data$lower <- subgroup_data$or * exp(-1.96 * 0.2)
subgroup_data$upper <- subgroup_data$or * exp(1.96 * 0.2)

tabviz(subgroup_data,
  label = "study",
  columns = list(
    viz_forest(
      point = "or", lower = "lower", upper = "upper",
      scale = "log", null_value = 1,
      axis_label = "Odds Ratio"
    )
  ),
  theme = web_theme_modern()
) |>
  split_table(by = c("sex", "age_group")) |>  # Hierarchical: Sex > Age Group
  forest_plot()

The sidebar shows “Sex” as the first level header, with “Age Group” nested under each sex.

Adding Extra Columns

Use columns to add extra data columns alongside the forest plot:

Code
tabviz(subgroup_data,
  label = "study",
  columns = list(
    col_text("sex", header = "Sex"),
    col_text("age_group", header = "Age"),
    col_interval("OR (95% CI)", point = "or", lower = "lower", upper = "upper"),
    viz_forest(
      point = "or", lower = "lower", upper = "upper",
      scale = "log", null_value = 1
    )
  ),
  theme = web_theme_modern()
) |>
  split_table(by = c("sex", "age_group")) |>
  forest_plot()

Shared Axis Range

By default, each sub-plot auto-scales its axis. Use shared_axis = TRUE for consistent comparison:

Code
tabviz(trial_data,
  label = "study",
  columns = list(
    viz_forest(
      point = "or", lower = "lower", upper = "upper",
      scale = "log", null_value = 1
    )
  ),
  theme = web_theme_modern()
) |>
  split_table(by = "region", shared_axis = TRUE) |>  # Same axis range across all regions
  forest_plot()

This ensures the same visual scale across all subgroups.

Exporting Split Forests

Export all sub-plots to a directory structure:

# Create split forest and save
p <- tabviz(data,
  label = "study",
  columns = list(
    viz_forest(point = "or", lower = "lower", upper = "upper")
  )
) |>
  split_table(by = c("sex", "age_group")) |>
  forest_plot()

# Export all sub-plots to: output/Male/Male_Young.svg, etc.
save_split_table(p, "output", format = "svg")

The directory structure mirrors the split hierarchy.

When to Use Split vs. Group

Feature group = split_by =
Display Single plot with collapsible rows Separate plots with sidebar
Navigation Click group headers Click sidebar items
Comparison All visible at once One subgroup at a time
Best for Small number of groups Many subgroups, detailed analysis

Use group when you want to see all data in one view with collapsible sections.

Use split_by when each subgroup deserves its own focused view, or when you have many subgroups that would clutter a single plot.