Learning gt: Creating a Retro League Table

R
data analysis
sports
Author

David Schoch

Published

November 18, 2024

It has been way too long since I had time to prepare a blog post that is neither a story about Open Source Development, or an announcement of yet another R package.

I meant to look into gt, a package to create wonderful-looking tables in R, for a very long time but everytime I get some sort of motivation, I shy away because of how complicated it looks to built a table. Hundreds of lines of codes for a 10 line table? Yeah no thank you knitr::kable() it is. But not this time.

Learning by breaking

Whenever I want to learn something new in R, I need a personal project for which this might be relevant. I am very bad at following tutorials. Basically all my data science, web scrapping, and javascript knowledge comes from my football analytics website that I have been maintaining for about 8 years. So I decided, why not football data again and decided to create a simple league table, but with a twist. I try to do something mildly absurd that requires enough extra effort to learn as much about the package as possible. When I wanted to built my first quarto website, I created quartocities, an homage to geocities and the beauty of 90s webpages. I didn’t break quarto, but got to learn so much about Lua, shortcodes, filters just to get those funky gifs everywhere. I am not gonna add that level of absurdity to the league table. For whatever reason, I decided that the table should have a vintage look. With this, I was hopping to get into as many of the styling elements as possible.

Setup

Besides the gt package, I will also use the gtExtras package which offers even more styling possibilities.

library(gt)
library(gtExtras)
library(tidyverse)

# some retro color palettes
cols <- c("#FAEBCC", "#b3e3e0", "#68C7C1", "#FACA78", "#F57F5B", "#DD5341", "#794A3A")
wld <- c("#354065", "#711233", "#666666")

The underlying data (current league table and results) was obtained from weltfussball.de.

Vanilla table

Here is the table without any form of styling.

tbl1 <- tbl |>
    gt()

tbl1
number img mannschaft pk sp wdl tore dif form
1 crests/bayern-munchen-2017-2025-logo.png Bayern München 26 10 8, 2, 0 33:7 26 W, W, W, W, D, D, W, W, W, W
2 crests/rb-leipzig-2020-logo.png RB Leipzig 21 10 6, 3, 1 15:5 10 W, W, D, D, W, W, W, W, L, D
3 crests/eintracht-frankfurt-1998-logo.png Eintracht Frankfurt 20 10 6, 2, 2 26:16 10 L, W, W, W, W, D, L, D, W, W
4 crests/bayer-04-leverkusen-2005-logo.png Bayer Leverkusen 17 10 4, 5, 1 21:16 5 W, L, W, W, D, D, W, D, D, D
5 crests/sc-freiburg-2008-logo.png SC Freiburg 17 10 5, 2, 3 13:11 2 W, L, W, W, L, W, W, L, D, D
6 crests/union-berlin-1966-logo.png 1. FC Union Berlin 16 10 4, 4, 2 9:8 1 D, W, D, W, L, W, W, D, L, D
7 crests/borussia-dortmund-1993-logo.png Borussia Dortmund 16 10 5, 1, 4 18:18 0 W, D, W, L, W, L, W, L, W, L
8 crests/werder-bremen-1987-logo.png Werder Bremen 15 10 4, 3, 3 17:21 -4 D, D, W, L, W, L, W, D, L, W
9 crests/borussia-monchengladbach-1999-logo.png Bor. Mönchengladbach 14 10 4, 2, 4 15:14 1 L, W, L, L, W, L, W, D, W, D
10 crests/mainz-2018-logo.png 1. FSV Mainz 05 13 10 3, 4, 3 15:14 1 D, D, L, W, L, W, L, D, D, W
11 crests/vfb-stuttgart-2014-logo.png VfB Stuttgart 13 10 3, 4, 3 19:19 0 L, D, W, W, D, D, L, W, D, L
12 crests/vfl-wolfsburg-2002-logo.png VfL Wolfsburg 12 10 3, 3, 4 19:18 1 L, W, L, L, D, W, L, D, D, W
13 crests/fc-augsburg-2002-logo.png FC Augsburg 12 10 3, 3, 4 13:20 -7 D, L, W, L, L, W, L, W, D, D
14 crests/1-fc-heidenheim-2007-logo.png 1. FC Heidenheim 1846 10 10 3, 1, 6 13:15 -2 W, W, L, L, W, L, L, D, L, L
15 crests/tsg-1899-hoffenheim-2014-logo.png 1899 Hoffenheim 9 10 2, 3, 5 13:19 -6 W, L, L, L, L, D, W, D, L, D
16 crests/st-pauli-2005-logo.png FC St. Pauli 8 10 2, 2, 6 7:12 -5 L, L, L, D, W, L, L, D, W, L
17 crests/holstein-kiel.png Holstein Kiel 5 10 1, 2, 7 12:25 -13 L, L, L, D, L, D, L, L, W, L
18 crests/vfl-bochum-2000-logo.png VfL Bochum 2 10 0, 2, 8 10:30 -20 L, L, L, D, L, L, L, L, L, D

Two things might catch your eye. There seem to be two list columns (wdl and form). We will deal with them later. In general, these types of columns are usually used to create som visualization WITHIN the column.

The column img contains paths to crests of the clubs. These can be displayed with the gt_img_rows() function from gtExtras. We also align the imiges with cols_align().

tbl1 <- tbl1 |>
    gt_img_rows(img, img_source = "local", height = "25px") |>
    cols_align(
        align = "center",
        columns = img
    )
tbl1
number img mannschaft pk sp wdl tore dif form
1 Bayern München 26 10 8, 2, 0 33:7 26 W, W, W, W, D, D, W, W, W, W
2 RB Leipzig 21 10 6, 3, 1 15:5 10 W, W, D, D, W, W, W, W, L, D
3 Eintracht Frankfurt 20 10 6, 2, 2 26:16 10 L, W, W, W, W, D, L, D, W, W
4 Bayer Leverkusen 17 10 4, 5, 1 21:16 5 W, L, W, W, D, D, W, D, D, D
5 SC Freiburg 17 10 5, 2, 3 13:11 2 W, L, W, W, L, W, W, L, D, D
6 1. FC Union Berlin 16 10 4, 4, 2 9:8 1 D, W, D, W, L, W, W, D, L, D
7