Table Template: Create your own {gt} table theme

gt
table
Author

Gutama Girja Urago

Published

April 2, 2024

Creating visually appealing and informative tables is a key aspect of data presentation, and the gt package in R provides powerful tools for this purpose. In this post, we will walk through creating a customizable table template using gt. By following these steps, you can easily create tables that are both functional and aesthetically pleasing, tailored to your specific needs. This blog post is motivated by this video on tutorial

Load Required Libraries

First, ensure that you have the gt package loaded. All function used below are from gt package, except the data setup which I showed where it comes from.

# install.packages("gt")        Run only once if don't have the package installed
library(gt)
library(tidyverse)              # For data manipulation

Prepare Your Data

For this example, we’ll use the iris dataset and select a subset of it. We’ll group the data by species and take the first two entries from each group. It is already appealing, but we can do better!

data <- iris |> 
        mutate(Species = stringr::str_to_title(Species)) |> 
        group_by(Species) |> 
        slice_head(n = 2) |>
        ungroup() |> 
        select(Species, everything())

tbl <- gt(data)
tbl
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
Setosa 5.1 3.5 1.4 0.2
Setosa 4.9 3.0 1.4 0.2
Versicolor 7.0 3.2 4.7 1.4
Versicolor 6.4 3.2 4.5 1.5
Virginica 6.3 3.3 6.0 2.5
Virginica 5.8 2.7 5.1 1.9

Add a Header

Next, add a title and subtitle to your table for better context and readability.

tbl <- tbl |> 
        tab_header(
                title = "Main Title",
                subtitle = "Subtitle"
        )

tbl
Main Title
Subtitle
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
Setosa 5.1 3.5 1.4 0.2
Setosa 4.9 3.0 1.4 0.2
Versicolor 7.0 3.2 4.7 1.4
Versicolor 6.4 3.2 4.5 1.5
Virginica 6.3 3.3 6.0 2.5
Virginica 5.8 2.7 5.1 1.9

Style the Header

Apply styling to the header to make it stand out. Here, we set the text color to blue and make it bold.

tbl <- tbl |> 
        tab_style(
                style = cell_text(color = "black", 
                                  weight = "bold"),
                locations = cells_title(groups = "title")
        )

tbl
Main Title
Subtitle
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
Setosa 5.1 3.5 1.4 0.2
Setosa 4.9 3.0 1.4 0.2
Versicolor 7.0 3.2 4.7 1.4
Versicolor 6.4 3.2 4.5 1.5
Virginica 6.3 3.3 6.0 2.5
Virginica 5.8 2.7 5.1 1.9

Style the Body

To enhance readability, apply a background color to alternating rows in the table body.

tbl <- tbl |> 
               tab_style(
                style = cell_fill(color = "grey90"),
                locations = cells_body(rows = seq(1, 6, 2))
        )

tbl
Main Title
Subtitle
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
Setosa 5.1 3.5 1.4 0.2
Setosa 4.9 3.0 1.4 0.2
Versicolor 7.0 3.2 4.7 1.4
Versicolor 6.4 3.2 4.5 1.5
Virginica 6.3 3.3 6.0 2.5
Virginica 5.8 2.7 5.1 1.9

Adjust Table Options

Customize the table width, column label background color, and heading alignment to suit your design preferences.

tbl <- tbl |>
        tab_options(
                table.width = pct(100),
                column_labels.background.color = "steelblue",
                heading.align = "left")

tbl
Main Title
Subtitle
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
Setosa 5.1 3.5 1.4 0.2
Setosa 4.9 3.0 1.4 0.2
Versicolor 7.0 3.2 4.7 1.4
Versicolor 6.4 3.2 4.5 1.5
Virginica 6.3 3.3 6.0 2.5
Virginica 5.8 2.7 5.1 1.9

Add Spanners

If your table has grouped columns, add spanners to better organize and present these groups.

tbl <- tbl |> 
        tab_spanner_delim(".")

tbl
Main Title
Subtitle
Species Sepal Petal
Length Width Length Width
Setosa 5.1 3.5 1.4 0.2
Setosa 4.9 3.0 1.4 0.2
Versicolor 7.0 3.2 4.7 1.4
Versicolor 6.4 3.2 4.5 1.5
Virginica 6.3 3.3 6.0 2.5
Virginica 5.8 2.7 5.1 1.9

Style Column Labels and Spanners

Ensure that your column labels and spanners are easily distinguishable by applying bold text and adjusting the size for spanners.

tbl <- tbl |> 
        tab_style(
                style = cell_text(weight = "bold"),
                locations = cells_column_labels()
        ) |> 
        tab_style(
                style = cell_text(weight = "bold",
                                  size = "medium"),
                locations = cells_column_spanners()
        )

tbl
Main Title
Subtitle
Species Sepal Petal
Length Width Length Width
Setosa 5.1 3.5 1.4 0.2
Setosa 4.9 3.0 1.4 0.2
Versicolor 7.0 3.2 4.7 1.4
Versicolor 6.4 3.2 4.5 1.5
Virginica 6.3 3.3 6.0 2.5
Virginica 5.8 2.7 5.1 1.9

Make it Reusable

We can write a reusable function that produces exactly the same theme.

my_gt_theme <- function(
                gt_table,
                title,
                subtitle,
                ...
                ) {
        
        rows <- nrow(gt_table[["_data"]])
        
        my_table <- gt_table |> 
                tab_header(
                title = title,
                subtitle = subtitle
        ) |> 
                tab_style(
                style = cell_text(color = "black", 
                                  weight = "bold"),
                locations = cells_title(groups = "title")
        ) |> 
                tab_style(
                style = cell_fill(color = "grey90"),
                locations = cells_body(rows = seq(1, rows, 2))
        ) |> 
                tab_options(
                table.width = pct(100),
                column_labels.background.color = "steelblue",
                heading.align = "left") |> 
                tab_style(
                style = cell_text(weight = "bold"),
                locations = cells_column_labels()
        ) |> 
        tab_style(
                style = cell_text(weight = "bold",
                                  size = "medium"),
                locations = cells_column_spanners()
        ) |> 
                tab_spanner_delim(...)
        
        return(my_table)
        
}

Then, we can store our function and apply it whenever we need it, without rewriting everything. It’s impressive to do all that with a few lines of code (See code chunk below).

gt(data) |> 
        my_gt_theme(
                title = "Easy and Beautiful Theme",
                subtitle = "With very minimal code",
                delim = "."
        )
Easy and Beautiful Theme
With very minimal code
Species Sepal Petal
Length Width Length Width
Setosa 5.1 3.5 1.4 0.2
Setosa 4.9 3.0 1.4 0.2
Versicolor 7.0 3.2 4.7 1.4
Versicolor 6.4 3.2 4.5 1.5
Virginica 6.3 3.3 6.0 2.5
Virginica 5.8 2.7 5.1 1.9

The end!