Create Beautiful Tables With GT Package In RStudio

Rafael
5 min readMay 2, 2023

--

Table created by author

In grad school I fell in love with data visualization. Data visualization is something I struggle with. There is a lot of second guessing. A lot of experimenting and failing.

I try and stick to the fundamentals or to my understanding of the fundamentals.

At the beginning of my journey into data visualization I was opposed to creating tables. I love the process of taking data from rows and columns and finding the story once you transformed the data into plots.

Project after project using bar plots, scatterplots, histograms, density plots etc…I started to struggle and began second guessing myself. Imposter syndrome grabbed me at the spine and climbed up pulling itself by every vertebrate until it settled on the back of my neck and shook hands with my anxiety.

I took the google course on coursera and obtained the certificate in data analysis. In the course they talked about tables and how they serve a purpose in telling the story.

I don’t know where I got the idea that tables were bad. Perhaps it was my pride after hours learning code to create plots on R-Studio and Python. Let’s chalk it up to my stupidity. The google data analysis certificate started my path to discover packages to create tables.

I found the GT package in R-Studio. I followed the documentation and started creating simple tables.

#load libraries
library(ggplot2)
library(RColorBrewer)
library(gtExtras)
library(gt)

The project that I used the gt package for the first time compared the performance between two Arizona Wildcat players.

I combined line-plots and central tendency table to compare the assists performance in the latter months of a the NCAA basketball season.

The first step was to create the line plots with ggplot2.

#create lineplot
#save plot under a value
kriisa_ast_feb <- ggplot(kriisa_february, aes(x = date, y = ast_rate)) +
geom_line(color = "red")+ #color the line red
geom_point(color = "blue")+ #color the point blue
geom_text(aes(label = opponent), size = 2, hjust = 0, vjust = -1)+#label the opponent next to the point
labs(x = "Date", y = "Assist Rate", title = "Kerr Kriisa Assist Rate in February")+ #add labels to x-axis, y-axis and title the plot
theme_classic()#use theme classic to remove background gridlines

kriisa_ast_feb

Ggplot created the following plot.

Next step was to create a simple table with the central tendency data for the month of February.

#create central tendency table
table_kri_ast_rate_february <- kriisa_ast_rate_february %>% #label table
gt()%>% #call up gt package
gt_theme_nytimes()%>% #package allows you to use publication themes(fonts).
tab_header(title = "Kerr Kriisa Assist Rate in February") %>% #provide title for the table
gt_color_rows(Mean:Mode)#add color to columns in the table. Function will color all columns within Mean and Mode

table_kri_ast_rate_february

The table has the NY Times font. Mean, median and mode are colored red. The purpose of adding color is to highlight the categories where one player out performs the other.

To create the final visualizations I exported the plots as pdf files so that I can make edits on adobe illustrator.

GT tables can be exported as png and other image files like jpg but you can not export as pdf. To transform the table into a pdf file I exported the table as an html file. When the web browser opens up, you can export the image as pdf by going to file -> export as pdf.

In illustrator I combined all the tables and plots into one visual. I removed the opponent names and added school logos to compare how each player performed against the same opponents.

In my next project I decided to solely use tables to make comparisons. I followed the Sacramento Kings vs Golden State Warriors series and created a table after each game to compare De’Aaron Fox and Steph Curry.

This is how I created the table.

curry_fox_table <- curry_fox2 %>% #give table a value name 
gt()%>%
#tab_header creates title and subtitle
#md allows you to use markdown to change text to bold, italics etc..;
tab_header(title = md("**Stephen Curry vs De'Aaron Fox**"),
subtitle = "2023 NBA Playoffs 1st Round")%>% #
#tab_row seperates columns into groups and allows you to label the group.
#md function uses markdown commands.
#rows function groups the rows from your data frame
tab_row_group(label = md("**Game 1**"),
rows = 1:2)%>%
tab_row_group(label = md("**Game 2**"),
rows = 3:4)%>%
tab_row_group(label = md("**Game 3**"),
rows = 5:6)%>%
tab_row_group(label = md("**Game 4**"),
rows = 7:8)%>%
tab_row_group(label = md("**Game 5**"),
rows = 9:10)%>%
tab_row_group(label = md("**Game 6**"),
rows = 11:12)%>%
tab_row_group(label = md("**Game 7**"),
rows = 13:14)%>%
#gt_color gives rows color through index or column name.
#palette allows you to create your color palette.
gt_color_rows("Usage %", palette = c("#ffffff","#5A2D81"))%>%
gt_color_rows("Offensive Rating", palette = c("#ffffff","#FFC72C"))%>%
gt_color_rows("Points", palette = c("#ffffff","#FFC72C"))%>%
gt_color_rows("Assists", palette = c("#ffffff","#5a2d81"))%>%
gt_color_rows("TS%", palette = c("#ffffff","#FFC72C"))%>%
gt_color_rows("eFG %", palette = c("#ffffff","#FFC72C"))%>%
gt_color_rows("FTr", palette = c("#ffffff","#5a2d81"))%>%
gt_color_rows("TO": "TO %", palette = c("#ffffff","#5a2d81"))%>%
#tab_option and table backgroun color gives table a background color
tab_options(table.background.color = "lightcyan")%>%
#tab_source_note allows you to add notes or source information.
tab_source_note(source_note = md("**Player with Highest Offensive Rating in each game has been on winning side**"))%>%
tab_source_note(source_note = md("**Columns with yellow = Variable where Curry has most games with higher value**"))%>%
tab_source_note(source_note = md("**Columns with purple = Variable where Fox has most games with higher value**"))%>%
#tab_spanner allows you to group columns together by a common theme
tab_spanner(label = md("**Offensive Effectiveness**"),
columns = c("Usage %", "Offensive Rating", "Points", "Assists"))%>%
tab_spanner(label = md("**Shooting Efficiency**"),
columns = c("TS%", "eFG %"))%>%
tab_spanner(label = md("**Carelessness**"),
columns = c("TO", "TO %"))


curry_fox_table

Final product

I started out simple and as I built the table game by game, I added different elements to the table.

As I have advanced in this data analysis journey I still find the documentation page to any package a bit intimidating. I can’t help but compare what a package can do to my lack of understanding and my novice abilities. Adding elements slowly to a project creates familiarity with the documentation.

The GT package creates beautiful tables and I have incorporated more and more to my sports analytics projects and business.

Subscribe to the FREE Newsletter

Visit the Websites

tr3ple-threat.com

dunkballrhymes.com

--

--

Rafael

I have a Masters in Information Management and Certificate of Advanced Studies in Data Science. I'm launching a business in sports analytics.