Control the visual appearance of individual rows using row_* parameters. This gives you precise control over text styling, indentation, colors, and badges—essential for creating publication-ready meta-analysis figures.

Text Styling

Control text appearance with row_bold, row_italic, and row_color:

Code
# Use glp1_trials which has pre-computed row_bold
data(glp1_trials)

text_demo <- glp1_trials |>
  filter(group == "Main Trials", row_type == "data") |>
  head(4) |>
  mutate(
    ritalic = !row_bold,
    rcolor = ifelse(row_bold, "#0369a1", "#64748b")
  )

tabviz(text_demo,
  label = "study",
  columns = list(
    col_text("drug", "Drug"),
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               null_value = 1, scale = "log")
  ),
  row_bold = "row_bold",
  row_italic = "ritalic",
  row_color = "rcolor"
)

Indentation

Create visual hierarchy with row_indent. Values represent nesting levels (0, 1, 2, …):

Code
indent_demo <- data.frame(
  label = c(
    "All Patients",
    "  Age < 65",
    "    Male", "    Female",
    "  Age >= 65",
    "    Male", "    Female"
  ),
  hr = c(0.78, 0.72, 0.70, 0.75, 0.85, 0.82, 0.88),
  lower = c(0.68, 0.58, 0.54, 0.60, 0.72, 0.66, 0.72),
  upper = c(0.89, 0.89, 0.91, 0.94, 1.00, 1.02, 1.08),
  rindent = c(0, 1, 2, 2, 1, 2, 2),
  rbold = c(TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE)
)

tabviz(indent_demo,
  label = "label",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               null_value = 1, scale = "log")
  ),
  row_indent = "rindent",
  row_bold = "rbold",
  theme = web_theme_modern()
)

Badges

Add small labels to highlight specific rows with row_badge:

Code
# nba_efficiency has an 'award' column perfect for badges
data(nba_efficiency)

nba_efficiency |>
  filter(conference == "East") |>
  head(6) |>
  tabviz(
    label = "player",
    columns = list(
      col_text("team", "Team", width = 60),
      col_numeric("ppg", "PPG"),
      viz_forest(point = "per", lower = "per_lower", upper = "per_upper",
                 null_value = 15, axis_label = "PER")
    ),
    row_badge = "award",
    row_bold = "all_star",
    theme = web_theme_modern()
  )

Badges are useful for marking awards, flagging key results, or indicating data quality.

TipSee Also

For more examples with badge data, see Package Data.


Background Colors

Highlight rows with row_bg for background colors:

Code
tabviz(data,
  label = "label",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               null_value = 1, scale = "log")
  ),
  row_bg = "background_color"  # Column with hex colors like "#f0f9ff"
)

Use sparingly—subtle tints work best.


Semantic Styling

For theme-aware styling that adapts automatically when you change themes, use semantic shortcuts:

Parameter Effect
row_emphasis Bold text + theme primary color (for key results)
row_muted Lighter color, reduced prominence (for secondary data)
row_accent Theme accent color (for highlighted findings)
Code
tabviz(data,
  label = "label",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               null_value = 1, scale = "log")
  ),
  row_emphasis = "is_primary",   # Column with TRUE/FALSE
  row_muted = "is_secondary"     # Column with TRUE/FALSE
)

These adapt automatically to any theme, so you don’t need to update color values when switching from web_theme_jama() to web_theme_lancet().


Expression-Based Styling

Instead of creating style columns in your data, you can use formula expressions that are evaluated on the fly. This is especially useful for conditional styling based on data values:

Code
expr_demo <- data.frame(
  study = c("Alpha 2020", "Beta 2021", "Gamma 2022", "Delta 2023"),
  hr = c(0.72, 0.85, 0.91, 0.68),
  lower = c(0.55, 0.70, 0.75, 0.52),
  upper = c(0.95, 1.03, 1.10, 0.89),
  pval = c(0.01, 0.1, 0.3, 0.005)
)

tabviz(expr_demo,
  label = "study",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               null_value = 1, scale = "log")
  ),
  # Formula expressions - no need for pre-computed columns
  row_bold = ~ pval < 0.05,
  row_color = ~ ifelse(pval < 0.05, "#166534", "#64748b"),
  title = "Expression-Based Styling",
  subtitle = "Bold + green color for significant results (p < 0.05)"
)

How It Works

  • Use the tilde (~) to start a formula expression
  • The expression is evaluated against your data frame
  • All column names in your data are available in the expression
  • Results should be logical (TRUE/FALSE) for boolean styles, or strings for colors

Multiple Conditions

Combine conditions using & (and) or | (or):

Code
# Bold if significant AND large effect
row_bold = ~ pval < 0.05 & hr < 0.8

# Emphasize if significant OR key study
row_emphasis = ~ pval < 0.05 | is_primary

# Color based on effect direction and significance
row_color = ~ case_when(
  hr < 1 & pval < 0.05 ~ "#166534",  # Significant benefit - green
  hr > 1 & pval < 0.05 ~ "#dc2626",  # Significant harm - red
  TRUE ~ "#64748b"                    # Non-significant - gray
)
TipWhen to Use Expressions vs Columns

Use formulas when:

  • Styling is based on simple conditions (pval < 0.05)
  • You want concise, readable code
  • Style logic is tightly coupled to the visualization

Use columns when:

  • Style values are pre-computed or loaded from data
  • Same styling is reused across multiple plots
  • Complex logic is better computed separately

Row Types

The row_type parameter controls fundamental row behavior. This is a manual approach for creating structured layouts with headers, summaries, and spacers—useful when you need precise control over the document structure.

Type Behavior Marker
"data" Standard data row Point with CI line
"header" Section header, spans full width None
"summary" Pooled/subtotal row Diamond shape
"spacer" Empty row for separation None
Code
# glp1_trials has pre-computed row_type column
glp1_trials |>
  filter(group == "Main Trials") |>
  head(5) |>
  tabviz(
    label = "study",
    columns = list(
      viz_forest(point = "hr", lower = "lower", upper = "upper",
                 null_value = 1, scale = "log")
    ),
    row_type = "row_type"
  )
ImportantNA Values for Non-Data Rows

Rows with row_type = "header" or "spacer" should have NA for point, lower, and upper. Summary rows need valid values to display the diamond.

TipRow Types vs Row Groups

For automatic grouping based on a column in your data, consider using the group parameter instead—it creates collapsible sections without manually specifying row types. See Row Groups.

NoteBuilt-in Dataset

The glp1_trials dataset includes pre-computed row_type and row_bold columns. See Package Data for details.


Complete Example: Meta-Analysis Figure

Here’s a publication-ready meta-analysis combining all row styling features:

Code
meta_analysis <- data.frame(
  label = c(
    "Cardiovascular Outcomes",
    "  EMPA-REG 2015", "  CANVAS 2017", "  DECLARE 2019", "  Subtotal", "",
    "Renal Outcomes",
    "  CREDENCE 2019", "  DAPA-CKD 2020", "  Subtotal", "",
    "Overall"
  ),
  hr = c(NA, 0.86, 0.86, 0.93, 0.88, NA, NA, 0.70, 0.61, 0.66, NA, 0.78),
  lower = c(NA, 0.74, 0.75, 0.84, 0.82, NA, NA, 0.59, 0.51, 0.57, NA, 0.73),
  upper = c(NA, 0.99, 0.97, 1.03, 0.95, NA, NA, 0.82, 0.72, 0.76, NA, 0.84),
  n = c(NA, 7020, 10142, 17160, 34322, NA, NA, 4401, 4304, 8705, NA, 43027),
  rtype = c(
    "header", "data", "data", "data", "summary", "spacer",
    "header", "data", "data", "summary", "spacer", "summary"
  ),
  rbold = c(TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE),
  rindent = c(0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0),
  rcolor = c("#0369a1", NA, NA, NA, "#0369a1", NA, "#0369a1", NA, NA, "#0369a1", NA, "#166534"),
  rbadge = c(NA, NA, NA, NA, "n=3", NA, NA, NA, NA, "n=2", NA, "n=5")
)

tabviz(meta_analysis,
  label = "label",
  columns = list(
    col_numeric("n", "N"),
    col_interval("HR (95% CI)", point = "hr", lower = "lower", upper = "upper"),
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               null_value = 1, scale = "log", axis_label = "Hazard Ratio (95% CI)")
  ),
  row_type = "rtype",
  row_bold = "rbold",
  row_indent = "rindent",
  row_color = "rcolor",
  row_badge = "rbadge",
  theme = web_theme_modern(),
  title = "SGLT2 Inhibitors Meta-Analysis",
  subtitle = "Cardiovascular and renal outcomes"
)

Fluent API Alternative

You can also apply row styling using set_row_style() for pipe-based workflows:

Code
tabviz(data,
  label = "label",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               null_value = 1, scale = "log")
  )
) |>
  set_row_style(
    type = "rtype",
    bold = "rbold",
    indent = "rindent",
    color = "rcolor",
    badge = "rbadge"
  )

This is useful when building styling programmatically or creating multiple variants from a base plot. See The Fluent API for more patterns.


Parameter Reference

All row_* parameters accept either a column name (string) or a formula expression (~ ...).

Parameter Column Contains Description
row_bold TRUE/FALSE Bold text
row_italic TRUE/FALSE Italic text
row_color CSS color (e.g., "#1a365d") Text color
row_bg CSS color Background color
row_indent Integer (0, 1, 2, …) Indentation level
row_badge Text Badge label
row_icon Emoji/unicode Icon before label
row_emphasis TRUE/FALSE Theme-aware emphasis styling
row_muted TRUE/FALSE Theme-aware muted styling
row_accent TRUE/FALSE Theme-aware accent styling
row_type "data", "header", "summary", "spacer" Row behavior and marker type
NoteFormula Examples
# Using column name
row_bold = "is_significant"

# Using formula expression
row_bold = ~ pval < 0.05

See Also