Installation

# Install from GitHub using pak
install.packages("pak")
pak::pak("kaskarn/tabviz")
NoteKey Concepts

Before diving in, here are the core concepts:

  • Label column: The row identifier (study name, category, item name, etc.)
  • Column types: col_*() for data columns, viz_*() for visualizations
  • Row types: "data" (normal row), "header" (section header), "summary" (totals/pooled), "spacer" (empty row)
  • Column mapping: Pass column names as strings—values are computed per-row

Your First Table

Create an interactive table with tabviz():

Code
# Use the built-in glp1_trials dataset
data(glp1_trials)

# Filter to main trial results
meta_data <- glp1_trials |>
  filter(row_type == "data", group == "Main Trials") |>
  head(5)

tabviz(meta_data,
  label = "study",
  columns = list(
    col_n("n"),
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               scale = "log", null_value = 1,
               axis_label = "Hazard Ratio (95% CI)"),
    col_interval("HR (95% CI)", point = "hr", lower = "lower", upper = "upper")
  )
)
TipBuilt-in Datasets

This example uses glp1_trials, one of five datasets included in the package. See Package Data for all available datasets.


Understanding the Code

The Core Pattern

tabviz(data,
  label = "label_column",    # Row labels
  columns = list(...)        # What columns to show
)

Column Types

Each col_*() function defines a column:

Function Purpose Example
col_text() Text col_text("category")
col_numeric() Numbers col_numeric("value", decimals = 1)
col_n() Sample sizes col_n("n")
viz_forest() Forest plot viz_forest(point = "hr", lower = "lo", upper = "hi")
col_interval() CI display col_interval("HR", point = "hr", lower = "lo", upper = "hi")
col_pvalue() P-values col_pvalue("pval")

See Columns for all 16+ column types.


Adding More Columns

Code
# Add drug name and events columns
tabviz(meta_data,
  label = "study",
  columns = list(
    col_text("drug", "Drug"),
    col_n("n"),
    col_numeric("events", header = "Events"),
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               scale = "log", null_value = 1),
    col_interval("HR (95% CI)", point = "hr", lower = "lower", upper = "upper")
  )
)

Applying Themes

tabviz includes 9 publication-ready themes:

Code
tabviz(meta_data[1:3, ],
  label = "study",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               scale = "log", null_value = 1)
  ),
  theme = web_theme_jama(), title = "JAMA"
)
tabviz(meta_data[1:3, ],
  label = "study",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               scale = "log", null_value = 1)
  ),
  theme = web_theme_lancet(), title = "Lancet"
)

Available themes: web_theme_default(), web_theme_jama(), web_theme_lancet(), web_theme_nature(), web_theme_cochrane(), web_theme_modern(), web_theme_presentation(), web_theme_dark(), web_theme_minimal()

See Themes for customization options.


Row Styling

Create visual hierarchy with row types and styling:

Code
styled_data <- data.frame(
  label = c("Primary Endpoint", "  CV Death", "  MI", "Summary"),
  hr = c(NA, 0.82, 0.79, 0.78),
  lower = c(NA, 0.72, 0.68, 0.65),
  upper = c(NA, 0.94, 0.92, 0.93),
  rtype = c("header", "data", "data", "summary"),
  rbold = c(TRUE, FALSE, FALSE, TRUE)
)

tabviz(styled_data,
  label = "label",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               scale = "log", null_value = 1),
    col_interval("HR (95% CI)", point = "hr", lower = "lower", upper = "upper")
  ),
  row_type = "rtype",
  row_bold = "rbold"
)
NoteRow Types
Type Behavior
"data" Standard row with interval marker
"header" Section header, no marker
"summary" Summary row with diamond marker
"spacer" Empty row for separation

Header and spacer rows should have NA for point, lower, and upper.


Conditional Styling

Style rows based on data values using formula expressions:

Code
tabviz(meta_data,
  label = "study",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               scale = "log", null_value = 1),
    col_interval("HR (95% CI)", point = "hr", lower = "lower", upper = "upper")
  ),
  row_bold = ~ upper < 1,  # Bold if significant
  marker_color = ~ ifelse(upper < 1, "#16a34a", "#64748b")  # Green if significant
)

Or use pre-computed columns:

Code
direction_data <- meta_data |>
  mutate(
    marker_color = case_when(
      upper < 1 ~ "#16a34a",  # Green: significant benefit
      lower > 1 ~ "#dc2626",  # Red: significant harm
      TRUE ~ "#64748b"        # Gray: not significant
    )
  )

tabviz(direction_data,
  label = "study",
  columns = list(
    viz_forest(point = "hr", lower = "lower", upper = "upper",
               scale = "log", null_value = 1)
  ),
  marker_color = "marker_color"
)

Next Steps

Topic What You’ll Learn
Columns All 16+ column types
Row Styling Headers, summaries, indentation, badges
Cell Styling Conditional formatting for individual cells
Row Groups Collapsible groups
Forest Plots Advanced forest column options
Themes Preset themes and customization