It produces nice display tables which are different from the data tables.
A display table is something which you often come across like tables in a web page, a journal article, or in a magazine.
Note: The display tables are output only and we are not going to use them as input ever again.
It helps in annotations, table element styling, and text transformations that serve to communicate the subject matter more clearly.
Example time - let’s see how does the gt package works
But before that - some basics:
# install.packages("tidyverse")
# install.packages("gt")
#install.packages("gtExtras")
#install.packages("svglite")
library(gt)
library(tidyverse)
library(gtExtras)
library(svglite)
A sneak peek into the dataset we are going to use - I hope you love “PIZZA”
data("pizzaplace")
“pizzaplace” is an in-built dataset under the gt package.
It has information about 32 different types of pizza in 4 different categories: classic, chicken, supreme, and veggie.
Let’s take a look at our dataset:
names(pizzaplace)
## [1] "id" "date" "time" "name" "size" "type" "price"
head(pizzaplace)
## # A tibble: 6 × 7
## id date time name size type price
## <chr> <chr> <chr> <chr> <chr> <chr> <dbl>
## 1 2015-000001 2015-01-01 11:38:36 hawaiian M classic 13.2
## 2 2015-000002 2015-01-01 11:57:40 classic_dlx M classic 16
## 3 2015-000002 2015-01-01 11:57:40 mexicana M veggie 16
## 4 2015-000002 2015-01-01 11:57:40 thai_ckn L chicken 20.8
## 5 2015-000002 2015-01-01 11:57:40 five_cheese L veggie 18.5
## 6 2015-000002 2015-01-01 11:57:40 ital_supr L supreme 20.8
Before using the gt package we need to have a table. Let’s create a table from our dataset using the dplyr functions.
The table we are creating is this: Total Sales by Pizza Size (2015)
# Group the data by pizza size and calculate total sales for each size
total_sales_by_size <- pizzaplace %>%
group_by(size) %>%
summarise(total_sales = sum(price))
# Calculate the overall total sales
overall_total_sales <- sum(total_sales_by_size$total_sales)
# Add a last row for overall total sales
total_sales_by_size <- total_sales_by_size %>%
add_row(size = "Overall Total", total_sales = overall_total_sales)
# Print the result
total_sales_by_size
## # A tibble: 6 × 2
## size total_sales
## <chr> <dbl>
## 1 L 375319.
## 2 M 249382.
## 3 S 178076.
## 4 XL 14076
## 5 XXL 1007.
## 6 Overall Total 817860.
Okay, so now we have a table. And here is the first use of gt on the new table - making a display table:
gt_table1 <- gt(total_sales_by_size)
gt_table1
size | total_sales |
---|---|
L | 375318.7 |
M | 249382.2 |
S | 178076.5 |
XL | 14076.0 |
XXL | 1006.6 |
Overall Total | 817860.1 |
Note: The main entry point into the gt API is the gt() function. If we pass total_sales_by_size to the function gt(), we’ll get a gt Table as output.
That doesn’t look too bad? It’s really basic but hey we didn’t ask for much:)
Now we will go ahead and learn about adding parts of a gt Table - if you remember the shiny table from the Presentation:). A brief introduction on them:
The way that we add parts like the Table Header and footnotes in the Table Footer is to use the **tab_*() family of functions. A Table Header** is easy to add so let’s see how the previous table looks with a title:
# Adding title to our display table
gt_table1 <- gt_table1 %>%
tab_header(
title = "Total Sales by Pizza Size (2015)"
)
gt_table1
Total Sales by Pizza Size (2015) | |
size | total_sales |
---|---|
L | 375318.7 |
M | 249382.2 |
S | 178076.5 |
XL | 14076.0 |
XXL | 1006.6 |
Overall Total | 817860.1 |
We want to get the best selling pizzas from this list. Also include the size and price and calculate the total revenue for each pizza.
top_5_pizzas <- pizzaplace %>%
group_by(name, size, price) %>%
count(name) %>%
arrange(desc(n)) %>%
head(5) %>%
mutate(rev = price * n) %>%
ungroup()
top_5_pizzas
## # A tibble: 5 × 5
## name size price n rev
## <chr> <chr> <dbl> <int> <dbl>
## 1 big_meat S 12 1914 22968
## 2 thai_ckn L 20.8 1410 29258.
## 3 five_cheese L 18.5 1409 26066.
## 4 four_cheese L 18.0 1316 23622.
## 5 classic_dlx M 16 1181 18896
So the top selling pizza combination is the small big_meat pizza!
Exercise 1: Lets change the table into a gt object and:
# Insert your answer here. Use https://gt.rstudio.com/reference/index.html as reference for the needed functions
top_5_table <- gt(top_5_pizzas) %>%
tab_header(title = md("**Top Five Best Selling Pizzas**"),
subtitle = md("Most Sold Pizza Combinations in 2015")) %>%
tab_spanner(label = "In 2015",
columns = c(n, rev)) %>%
cols_label(
name = "Pizza Name",
size = "Pizza Size",
price = "Price",
n = "Pizzas Sold",
rev = "Revenue per Pizza") %>%
fmt_number(columns = rev, decimals = 0)
top_5_table
Top Five Best Selling Pizzas | ||||
Most Sold Pizza Combinations in 2015 | ||||
Pizza Name | Pizza Size | Price | In 2015 | |
---|---|---|---|---|
Pizzas Sold | Revenue per Pizza | |||
big_meat | S | 12.00 | 1914 | 22,968 |
thai_ckn | L | 20.75 | 1410 | 29,258 |
five_cheese | L | 18.50 | 1409 | 26,066 |
four_cheese | L | 17.95 | 1316 | 23,622 |
classic_dlx | M | 16.00 | 1181 | 18,896 |
Okay so now we have a neat table with a Title followed by Subtitle. This looks neat and clean than the first one we created. Yay!
Now, what can we do more to this: maybe we can group some rows together, we can add a highlight color to one of the cells, and maybe we can give the borders some color. To group rows together, we can use the tab_row_group() function. The syntax for this function is:
tab_row_group(data, label, rows, id = label, others_label = NULL, group = NULL)
With the tab_style() function we can target specific cells and apply styles to them. This is best done in conjunction with the helper functions cell_text(), cell_fill(), and cell_borders(). Here are some of the styles we can apply:
Exercise 2:
# Insert your answer here. Use the functions mentioned above.
top_5_table <- top_5_table %>%
tab_options(heading.background.color = 'blue') %>%
tab_options(column_labels.font.weight = 'bold',
column_labels.background.color = 'lightgrey') %>%
tab_style(
style = cell_text(style = 'italic'),
locations = cells_title(groups = 'subtitle'))
top_5_table
Top Five Best Selling Pizzas | ||||
Most Sold Pizza Combinations in 2015 | ||||
Pizza Name | Pizza Size | Price | In 2015 | |
---|---|---|---|---|
Pizzas Sold | Revenue per Pizza | |||
big_meat | S | 12.00 | 1914 | 22,968 |
thai_ckn | L | 20.75 | 1410 | 29,258 |
five_cheese | L | 18.50 | 1409 | 26,066 |
four_cheese | L | 17.95 | 1316 | 23,622 |
classic_dlx | M | 16.00 | 1181 | 18,896 |
2.2. In the current table we have three Pizza Size - S, L, and M. How will you group the table so that you have three row groups?
# Insert your answer here. Use the functions mentioned above.
top_5_table <- top_5_table %>%
tab_row_group(
id = "S",
label = "Pizza Size - S",
rows = 1
) %>%
tab_row_group(
id = "L",
label = "Pizza Size - L",
rows = c(2,3,4)
) %>%
tab_row_group(
id = "M",
label = "Pizza Size - M",
rows = 5
)
top_5_table
Top Five Best Selling Pizzas | ||||
Most Sold Pizza Combinations in 2015 | ||||
Pizza Name | Pizza Size | Price | In 2015 | |
---|---|---|---|---|
Pizzas Sold | Revenue per Pizza | |||
Pizza Size - M | ||||
classic_dlx | M | 16.00 | 1181 | 18,896 |
Pizza Size - L | ||||
thai_ckn | L | 20.75 | 1410 | 29,258 |
five_cheese | L | 18.50 | 1409 | 26,066 |
four_cheese | L | 17.95 | 1316 | 23,622 |
Pizza Size - S | ||||
big_meat | S | 12.00 | 1914 | 22,968 |
In the next exercise we will be using gtExtras to go above an beyond. * Create a bar plot in every row that indicates the revenue from each pizza * Use the New York Times theme * Add a picture next to the title representing your favorite pizza. Use a picture URL from the web
# Insert your answer here. Use https://jthomasmock.github.io/gtExtras/reference/index.html as reference for the needed functions
top_5_table %>%
gt_plt_bar(column = rev, keep_column = TRUE) %>%
gt_theme_nytimes() %>%
tab_header(
title = add_text_img(
"Top Five Best Selling Pizzas",
url = "https://images.ctfassets.net/nw5k25xfqsik/64VwvKFqxMWQORE10Tn8pY/200c0538099dc4d1cf62fd07ce59c2af/20220211142754-margherita-9920.jpg?w=1024"
))
Top Five Best Selling Pizzas |
|||||
Pizza Name | Pizza Size | Price | In 2015 | rev | |
---|---|---|---|---|---|
Pizzas Sold | Revenue per Pizza | ||||
Pizza Size - M | |||||
classic_dlx | M | 16.00 | 1181 | 18,896 | |
Pizza Size - L | |||||
thai_ckn | L | 20.75 | 1410 | 29,258 | |
five_cheese | L | 18.50 | 1409 | 26,066 | |
four_cheese | L | 17.95 | 1316 | 23,622 | |
Pizza Size - S | |||||
big_meat | S | 12.00 | 1914 | 22,968 |
Further exercises for your own practice: Do you wanna work your way through a new dataset from the basics, then this script is for you. Just follow along and enjoy the process. Always remember the steps: first from the main dataset you should have a table ready for the outside world and then you use the gt package for formatting your display table.
# install.packages("tidyverse")
# install.packages("gt")
# install.packages("gtExtras")
# library(tidyverse)
# library(gt)
# library(gtExtras)
# Loading and getting a preview of the dataset
data("presidential")
head(presidential)
## # A tibble: 6 × 4
## name start end party
## <chr> <date> <date> <chr>
## 1 Eisenhower 1953-01-20 1961-01-20 Republican
## 2 Kennedy 1961-01-20 1963-11-22 Democratic
## 3 Johnson 1963-11-22 1969-01-20 Democratic
## 4 Nixon 1969-01-20 1974-08-09 Republican
## 5 Ford 1974-08-09 1977-01-20 Republican
## 6 Carter 1977-01-20 1981-01-20 Democratic
names(presidential)
## [1] "name" "start" "end" "party"
# Let's make a new table from this dataset. I want a table with the President and their party affiliation
name_party <- presidential %>%
distinct(name, party)
name_party
## # A tibble: 11 × 2
## name party
## <chr> <chr>
## 1 Eisenhower Republican
## 2 Kennedy Democratic
## 3 Johnson Democratic
## 4 Nixon Republican
## 5 Ford Republican
## 6 Carter Democratic
## 7 Reagan Republican
## 8 Bush Republican
## 9 Clinton Democratic
## 10 Obama Democratic
## 11 Trump Republican
Now the first step: Change the table in gt object.
# Insert your solution here.
Solution:
table1 <- gt(name_party)
table1
name | party |
---|---|
Eisenhower | Republican |
Kennedy | Democratic |
Johnson | Democratic |
Nixon | Republican |
Ford | Republican |
Carter | Democratic |
Reagan | Republican |
Bush | Republican |
Clinton | Democratic |
Obama | Democratic |
Trump | Republican |
Add title and subtitle to our display table:
# Insert your solution here.
Solution:
table1 <- table1 %>%
tab_header(
title = "American President and the Party",
subtitle = "American Presidents and their party affiliation"
)
table1
American President and the Party | |
American Presidents and their party affiliation | |
name | party |
---|---|
Eisenhower | Republican |
Kennedy | Democratic |
Johnson | Democratic |
Nixon | Republican |
Ford | Republican |
Carter | Democratic |
Reagan | Republican |
Bush | Republican |
Clinton | Democratic |
Obama | Democratic |
Trump | Republican |
Let’s make the title and subtitle standout - use of bold and italics: Add title and subtitle to our display table:
# Insert your solution here.
Solution:
table1 <- table1 %>%
tab_header(
title = md("**American President and the Party**"),
subtitle = md("*American Presidents and their party affiliation*")
)
table1
American President and the Party | |
American Presidents and their party affiliation | |
name | party |
---|---|
Eisenhower | Republican |
Kennedy | Democratic |
Johnson | Democratic |
Nixon | Republican |
Ford | Republican |
Carter | Democratic |
Reagan | Republican |
Bush | Republican |
Clinton | Democratic |
Obama | Democratic |
Trump | Republican |
Don’t forget to give the credits - rule no. 1 of good research practice (hint: use tab_source_note())
# Insert your solution here.
Solution:
table1 <- table1 %>%
tab_source_note(
source_note = "Source: The 'presidential' package in ggplot2"
)
table1
American President and the Party | |
American Presidents and their party affiliation | |
name | party |
---|---|
Eisenhower | Republican |
Kennedy | Democratic |
Johnson | Democratic |
Nixon | Republican |
Ford | Republican |
Carter | Democratic |
Reagan | Republican |
Bush | Republican |
Clinton | Democratic |
Obama | Democratic |
Trump | Republican |
Source: The 'presidential' package in ggplot2 |
What to do if you want to share a information with your audience in the table: Add a footnote indicating that Kennedy only served two terms:
# Insert your solution here.
Solution:
ttable1 <- table1 %>%
tab_footnote(
footnote = "He was president for only 2 years",
locations = cells_body(columns = name, rows = 2)
)
table1
American President and the Party | |
American Presidents and their party affiliation | |
name | party |
---|---|
Eisenhower | Republican |
Kennedy | Democratic |
Johnson | Democratic |
Nixon | Republican |
Ford | Republican |
Carter | Democratic |
Reagan | Republican |
Bush | Republican |
Clinton | Democratic |
Obama | Democratic |
Trump | Republican |
Source: The 'presidential' package in ggplot2 |
Now we want two groups in the table - a group of democratic presidents and a group of republican presidents. Split up the table into two row groups:
# Insert your solution here.
Solution
table1 <- table1 %>%
tab_row_group(
id = "Republican", # Unique ID
label = "Republican Party",
rows = c(1, 4, 5, 7, 8, 11)
) %>%
tab_row_group(
id = "Democratic", # Unique ID
label = "Democratic Party",
rows = c(2, 3, 6, 9, 10)
)
table1
American President and the Party | |
American Presidents and their party affiliation | |
name | party |
---|---|
Democratic Party | |
Kennedy | Democratic |
Johnson | Democratic |
Carter | Democratic |
Clinton | Democratic |
Obama | Democratic |
Republican Party | |
Eisenhower | Republican |
Nixon | Republican |
Ford | Republican |
Reagan | Republican |
Bush | Republican |
Trump | Republican |
Source: The 'presidential' package in ggplot2 |
The table is ready and now we want to try out some functions from the gtExtras package.
Use the package to edit the table to look like the tables in a NYT articles:
gt_theme_nytimes(table1)
American President and the Party | |
American Presidents and their party affiliation | |
name | party |
---|---|
Democratic Party | |
Kennedy | Democratic |
Johnson | Democratic |
Carter | Democratic |
Clinton | Democratic |
Obama | Democratic |
Republican Party | |
Eisenhower | Republican |
Nixon | Republican |
Ford | Republican |
Reagan | Republican |
Bush | Republican |
Trump | Republican |
Source: The 'presidential' package in ggplot2 |
I am a dark mode fan and I want my table in the dark mode:
gt_theme_dark(table1)
American President and the Party | |
American Presidents and their party affiliation | |
name | party |
---|---|
Democratic Party | |
Kennedy | Democratic |
Johnson | Democratic |
Carter | Democratic |
Clinton | Democratic |
Obama | Democratic |
Republican Party | |
Eisenhower | Republican |
Nixon | Republican |
Ford | Republican |
Reagan | Republican |
Bush | Republican |
Trump | Republican |
Source: The 'presidential' package in ggplot2 |
There are many more things you can do with the gt and gtExtras. Don’t forget you just have to put a question mark to get more information about them. ?gt ?gtExtras
Or you can get more info on these links: https://gt.rstudio.com/index.html and https://jthomasmock.github.io/gtExtras/index.html