library(gt)
library(tidyverse)
data("ChickWeight")
Fancy Tables in R
Photo by Juan Gomez on Unsplash
Introduction
As a continuation from my previous post exploring the use of the Stargazer library to create better looking tables, I thought I would look into the GT library. The GT library takes a different approach by creating an object class with the GT function. It is still able to create great looking tables in html or latex, but also adds support for RTF.
GT Library Intuition
The use of the GT library is pretty simple and starts with the creation of a GT object. For this example, I will use the ChickenWeight database that looks at the weights of different chickens.
The dataframe or tibble is passed into the GT function, which can be passed into additional modifier functions. This is better outlined and easier understood using the piping operator from the magrittr library, which is also included in the tidyverse library. The piping operator is incredibly useful and common.
%>% head() %>% gt() ChickWeight
weight | Time | Chick | Diet |
---|---|---|---|
42 | 0 | 1 | 1 |
51 | 2 | 1 | 1 |
59 | 4 | 1 | 1 |
64 | 6 | 1 | 1 |
76 | 8 | 1 | 1 |
93 | 10 | 1 | 1 |
The result is a simple a clean table the displays the required data. There is a set structure for the GT objects, which is outlined in the following diagram:
Function Chaining
As previously mentioned, by chaining GT functions together, we can add elements to the table. These elements can include titles, footnotes, source notes and conditional formatting similar to what you would use in an Excel table.
%>%
ChickWeight head() %>%
gt() %>%
tab_header(
title = "Chicken Weight data",
subtitle = "remember to weight your chickens!"
%>%
) tab_footnote(footnote = "measured in seconds",
locations = cells_column_labels(Time)) %>%
tab_source_note(source_note = "From ChickenWeight Database") %>%
tab_style(style = cell_fill(color = "red"),
locations = cells_body(
columns = weight,
rows = weight > 50
%>%
)) summary_rows(columns = c(weight,Time),
fns = list(
avg = ~mean(., na.rm = TRUE),
total = ~sum(., na.rm = TRUE),
s.d. = ~sd(., na.rm = TRUE))
)
Chicken Weight data | ||||
---|---|---|---|---|
remember to weight your chickens! | ||||
weight | Time1 | Chick | Diet | |
42 | 0 | 1 | 1 | |
51 | 2 | 1 | 1 | |
59 | 4 | 1 | 1 | |
64 | 6 | 1 | 1 | |
76 | 8 | 1 | 1 | |
93 | 10 | 1 | 1 | |
avg | 64.17 | 5.00 | — | — |
total | 385.00 | 30.00 | — | — |
s.d. | 18.24 | 3.74 | — | — |
From ChickenWeight Database | ||||
1 measured in seconds |
Helper functions
The previous code includes smaller helper functions within the element functions. These functions (ex. cells_body) provide targeting information for locations or conditioning. There is a learning curve for these functions, I would recommend looking them up as you work on your table rather than trying to learn them all. The everything() function seems to be of particular usefulness, as it allows you to use all values, such as all columns.
Additional notes
The summary_rows function can create summary rows for each grouping if the grouping is defined in the function or if the data is grouped itself. You can then use the grand_summary_rows function to create a grand summary.
It is always good practice to pass the na.rm = TRUE for your summary functions. Without it, you can create undesirable results.
A useful resource for learning the GT library is an article on R studio found here. It goes through more in depth on the topics that I have skimmed over.