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.
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!