Short Recap: What does gt package do?

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. table from The Hindu

Note: The display tables are output only and we are not going to use them as input ever again.

What more can gt do?

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

Execise 1:The Top 5 Best Selling Pizzas

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

Solution Exercise 1:

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

Exercise 2: Bringing Color into gt-Tables

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.

Solution for Exercise 2.1:

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.

Solution for Exercise 2.2:

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

Exercise 3: Using gtExtras

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

Solution for Exercise 3:

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

Thank You for Your Attention

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