gt cookbook

A cookbook of core examples with extending {gt}

Introduction

This cookbook attempts to walk through many of the example usecases for gt, and provide useful commentary around the use of the various gt functions. The full gt documentation has other more succinct examples and full function arguments.

For advanced use cases, make sure to check out the Advanced Cookbook

Basic Usage

To create a gt table, use gt() on a data frame.

mpg cyl disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
# pipe also works just fine!
head(mtcars) %>% 
  gt()
mpg cyl disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Preview long table

Sometimes you may want to see just a small portion of your input data. We can use gt_preview() in place of gt() to get the first x rows of data and the last y rows of data (which can be set by the top_n and bottom_n arguments).

gtcars %>%
  dplyr::select(mfr, model, year) %>%
  gt_preview()
mfr model year
1 Ford GT 2017
2 Ferrari 458 Speciale 2015
3 Ferrari 458 Spider 2015
4 Ferrari 458 Italia 2014
5 Ferrari 488 GTB 2016
6..46
47 Rolls-Royce Wraith 2016

Save output

While the vast majority of the time you will simply execute the code inside RMarkdown or Shiny and get your beautiful table back, you can explicitly save the output to various different formats.

gtsave() is the function, and it takes a gt table object and a filename.

The gtsave() function makes it easy to save a gt table to a file. The function guesses the file type by the extension provided in the output filename, producing either an HTML, PDF, PNG, LaTeX, or RTF file.

The most traditional format is HTML, which can be embedded into an existing website (ie Wordpress or a CMS), but the other formats (PDF, LaTex, RTF, PNG) have other use cases.

PDF can be combined with other PDF formats, LaTeX can be placed into an existing doc, RTF can be copied into Word, Excel, or Powerpoint, and PNG can be used to post images of tables to social media like Twitter.

Raw output

There are also functions for as_raw_html() or as_rtf() which allow you to get the raw output in the active R session. These are useful but seldom actually used unless for specific reasons. Again, in most examples you will simply call the gt code in your RMarkdown or Shiny app.

Grouping and Summary Rows

You can group rows in a table by specifying one or more columns in groupname_col:

head(mtcars) %>% 
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  gt(groupname_col = "cyl")
mpg disp hp drat wt qsec vs am gear carb
6 Cylinders
21.0 160 110 3.90 2.620 16.46 0 1 4 4
21.0 160 110 3.90 2.875 17.02 0 1 4 4
21.4 258 110 3.08 3.215 19.44 1 0 3 1
18.1 225 105 2.76 3.460 20.22 1 0 3 1
4 Cylinders
22.8 108 93 3.85 2.320 18.61 1 1 4 1
8 Cylinders
18.7 360 175 3.15 3.440 17.02 0 0 3 2

Or by simply using dplyr::group_by()

head(mtcars) %>% 
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  group_by(cyl) %>% 
  gt()
mpg disp hp drat wt qsec vs am gear carb
6 Cylinders
21.0 160 110 3.90 2.620 16.46 0 1 4 4
21.0 160 110 3.90 2.875 17.02 0 1 4 4
21.4 258 110 3.08 3.215 19.44 1 0 3 1
18.1 225 105 2.76 3.460 20.22 1 0 3 1
4 Cylinders
22.8 108 93 3.85 2.320 18.61 1 1 4 1
8 Cylinders
18.7 360 175 3.15 3.440 17.02 0 0 3 2

Custom groups

You can also create custom groups with gt::tab_row_group(). This is typically useful for creating your own groups within gt itself, and it can include specific rows based on a logical statement (ie hp > 600).

gtcars %>%
  dplyr::select(model, year, hp, trq) %>%
  head(8) %>% 
  gt() %>% 
  tab_row_group(
    group = "powerful",
    rows = hp <= 600
  ) %>%
  tab_row_group(
    group = "super powerful",
    rows = hp > 600
  )
model year hp trq
super powerful
GT 2017 647 550
488 GTB 2016 661 561
GTC4Lusso 2017 680 514
FF 2015 652 504
powerful
458 Speciale 2015 597 398
458 Spider 2015 562 398
458 Italia 2014 562 398
California 2015 553 557

You can also create meta-groups of a grouping category this way.

gtcars %>% 
  dplyr::select(mfr:hp, mpg_c, mpg_h) %>% 
  dplyr::filter(mfr %in% c("Ford", "Dodge", "Chevrolet", "Nissan", "Acura")) %>% 
  gt() %>% 
  tab_row_group(
    group = "Japanese",
    rows = mfr %in% c("Nissan", "Acura")
  ) %>% 
  tab_row_group(
    group = "American",
    rows = mfr %in% c("Ford", "Dodge", "Chevrolet")
  )
mfr model year trim bdy_style hp mpg_c mpg_h
American
Ford GT 2017 Base Coupe coupe 647 11 18
Chevrolet Corvette 2016 Z06 Coupe coupe 650 15 22
Dodge Viper 2017 GT Coupe coupe 645 12 19
Japanese
Acura NSX 2017 Base Coupe coupe 573 21 22
Nissan GT-R 2016 Premium Coupe coupe 545 16 22

Row names

You can also convert a column into table rownames and specify it in the original gt() call.

head(mtcars) %>% 
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  gt(rowname_col = "cyl")
mpg disp hp drat wt qsec vs am gear carb
6 Cylinders 21.0 160 110 3.90 2.620 16.46 0 1 4 4
6 Cylinders 21.0 160 110 3.90 2.875 17.02 0 1 4 4
4 Cylinders 22.8 108 93 3.85 2.320 18.61 1 1 4 1
6 Cylinders 21.4 258 110 3.08 3.215 19.44 1 0 3 1
8 Cylinders 18.7 360 175 3.15 3.440 17.02 0 0 3 2
6 Cylinders 18.1 225 105 2.76 3.460 20.22 1 0 3 1

If you have a data.frame with rownames attached, you can use the rownames_to_stub argument to parse these properly.

head(mtcars) %>% 
  gt(rownames_to_stub = TRUE)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

However, a tibble will drop rownames, so you can convert a data.frame’s existing rownames to a column with tibble::rownames_to_column(). gt will automatically use columns named rowname as a rowname stub.

head(mtcars) %>% 
  tibble::rownames_to_column() %>% 
  gt()
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Rownames and groups

Combining rownames with groups can sometimes make the table easier to parse. Compare the two tables below:

mtcars %>% 
  head() %>% 
  select(cyl, mpg:drat) %>% 
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  gt(groupname_col = "cyl")
mpg disp hp drat
6 Cylinders
21.0 160 110 3.90
21.0 160 110 3.90
21.4 258 110 3.08
18.1 225 105 2.76
4 Cylinders
22.8 108 93 3.85
8 Cylinders
18.7 360 175 3.15
head(mtcars) %>% 
  select(cyl, mpg:drat) %>% 
  tibble::rownames_to_column() %>% 
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  gt(groupname_col = "cyl", rowname_col = "rowname")
mpg disp hp drat
6 Cylinders
Mazda RX4 21.0 160 110 3.90
Mazda RX4 Wag 21.0 160 110 3.90
Hornet 4 Drive 21.4 258 110 3.08
Valiant 18.1 225 105 2.76
4 Cylinders
Datsun 710 22.8 108 93 3.85
8 Cylinders
Hornet Sportabout 18.7 360 175 3.15

Create blank rownames

I typically will use a rowname column whenever I group data, but sometimes there may not be a “good” column to use here. You can pass in blank spaces to artificially move the group label to be presented closer to a “stub”.

head(mtcars) %>% 
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  mutate(blank_rowname = purrr::map(list(rep("&nbsp", 8)), gt::html)) %>% 
  gt(rowname_col = "blank_rowname", groupname_col = "cyl")
mpg disp hp drat wt qsec vs am gear carb
6 Cylinders
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp 21.0 160 110 3.90 2.620 16.46 0 1 4 4
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp 21.0 160 110 3.90 2.875 17.02 0 1 4 4
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp 21.4 258 110 3.08 3.215 19.44 1 0 3 1
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp 18.1 225 105 2.76 3.460 20.22 1 0 3 1
4 Cylinders
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp 22.8 108 93 3.85 2.320 18.61 1 1 4 1
8 Cylinders
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp 18.7 360 175 3.15 3.440 17.02 0 0 3 2

Summary Rows

When rows are grouped, you can create summary rows in a column using the summary_rows function:

mtcars %>% 
  head(8) %>% 
  tibble::rownames_to_column(var = "name") %>%
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  gt(groupname_col = "cyl", rowname_col = "name") %>% 
  summary_rows(
    groups = TRUE,
    fns = list(Average = ~mean(.))
    )
mpg disp hp drat wt qsec vs am gear carb
6 Cylinders
Mazda RX4 21.0 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 160.0 110 3.90 2.875 17.02 0 1 4 4
Hornet 4 Drive 21.4 258.0 110 3.08 3.215 19.44 1 0 3 1
Valiant 18.1 225.0 105 2.76 3.460 20.22 1 0 3 1
Average 20.38 200.75 108.75 3.41 3.04 18.29 0.50 0.50 3.50 2.50
4 Cylinders
Datsun 710 22.8 108.0 93 3.85 2.320 18.61 1 1 4 1
Merc 240D 24.4 146.7 62 3.69 3.190 20.00 1 0 4 2
Average 23.60 127.35 77.50 3.77 2.75 19.30 1.00 0.50 4.00 1.50
8 Cylinders
Hornet Sportabout 18.7 360.0 175 3.15 3.440 17.02 0 0 3 2
Duster 360 14.3 360.0 245 3.21 3.570 15.84 0 0 3 4
Average 16.50 360.00 210.00 3.18 3.50 16.43 0.00 0.00 3.00 3.00

Further customization of Summary Rows

You can pass additional summarization functions to the fns argument, optionally specify columns to apply the summary to, and apply a formatter to format the output.

mtcars %>% 
  head(8) %>% 
  tibble::rownames_to_column(var = "name") %>%
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  gt(groupname_col = "cyl", rowname_col = "name") %>% 
  summary_rows(
    groups = TRUE,
    columns = c(mpg, disp, hp),
    fns = list(
      min = ~min(.),
      max = ~max(.),
      avg = ~mean(.)
      ),
    formatter = fmt_number
    )
mpg disp hp drat wt qsec vs am gear carb
6 Cylinders
Mazda RX4 21.0 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 160.0 110 3.90 2.875 17.02 0 1 4 4
Hornet 4 Drive 21.4 258.0 110 3.08 3.215 19.44 1 0 3 1
Valiant 18.1 225.0 105 2.76 3.460 20.22 1 0 3 1
min 18.10 160.00 105.00
max 21.40 258.00 110.00
avg 20.38 200.75 108.75
4 Cylinders
Datsun 710 22.8 108.0 93 3.85 2.320 18.61 1 1 4 1
Merc 240D 24.4 146.7 62 3.69 3.190 20.00 1 0 4 2
min 22.80 108.00 62.00
max 24.40 146.70 93.00
avg 23.60 127.35 77.50
8 Cylinders
Hornet Sportabout 18.7 360.0 175 3.15 3.440 17.02 0 0 3 2
Duster 360 14.3 360.0 245 3.21 3.570 15.84 0 0 3 4
min 14.30 360.00 175.00
max 18.70 360.00 245.00
avg 16.50 360.00 210.00

You can use any of R’s built-in aggregate functions, or a custom function.

# some examples
sum()     # Sum of numbers
mean()    # Mean of numbers
max()     # Maximum of numbers
min()     # Minimum of numbers
median()  # Median of numbers
sd()      # Standard Deviation of numbers

Or a custom aggregate function: ::: {.cell}

mode <- function(x) {
  unique_var <- unique(x)
  unique_var[which.max(tabulate(match(x, unique_var)))]
}

:::

Multiple groups

You can supply multiple groups via dplyr::group_by(), which are then appended with a - separator.

head(mtcars, 8) %>% 
  tibble::rownames_to_column(var = "name") %>%
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  group_by(cyl, gear) %>% 
  arrange(cyl) %>%
  gt(rowname_col = "name") %>% 
  summary_rows(
    groups = TRUE,
    fns = list(Average = ~mean(.))
    )
mpg disp hp drat wt qsec vs am carb
4 Cylinders - 4
Datsun 710 22.8 108.0 93 3.85 2.320 18.61 1 1 1
Merc 240D 24.4 146.7 62 3.69 3.190 20.00 1 0 2
Average 23.60 127.35 77.50 3.77 2.75 19.30 1.00 0.50 1.50
6 Cylinders - 4
Mazda RX4 21.0 160.0 110 3.90 2.620 16.46 0 1 4
Mazda RX4 Wag 21.0 160.0 110 3.90 2.875 17.02 0 1 4
Average 21.00 160.00 110.00 3.90 2.75 16.74 0.00 1.00 4.00
6 Cylinders - 3
Hornet 4 Drive 21.4 258.0 110 3.08 3.215 19.44 1 0 1
Valiant 18.1 225.0 105 2.76 3.460 20.22 1 0 1
Average 19.75 241.50 107.50 2.92 3.34 19.83 1.00 0.00 1.00
8 Cylinders - 3
Hornet Sportabout 18.7 360.0 175 3.15 3.440 17.02 0 0 2
Duster 360 14.3 360.0 245 3.21 3.570 15.84 0 0 4
Average 16.50 360.00 210.00 3.18 3.50 16.43 0.00 0.00 3.00

Grand summary

Grand summary rows incorporate all of the available data, regardless of whether some of the data are part of row groups.

head(mtcars, 8) %>% 
  tibble::rownames_to_column(var = "name") %>%
  mutate(cyl = paste(cyl, "Cylinders")) %>% 
  gt(rowname_col = "name", groupname_col = "cyl") %>% 
  grand_summary_rows(fns = list(Average = ~mean(.)))
mpg disp hp drat wt qsec vs am gear carb
6 Cylinders
Mazda RX4 21.0 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 160.0 110 3.90 2.875 17.02 0 1 4 4
Hornet 4 Drive 21.4 258.0 110 3.08 3.215 19.44 1 0 3 1
Valiant 18.1 225.0 105 2.76 3.460 20.22 1 0 3 1
4 Cylinders
Datsun 710 22.8 108.0 93 3.85 2.320 18.61 1 1 4 1
Merc 240D 24.4 146.7 62 3.69 3.190 20.00 1 0 4 2
8 Cylinders
Hornet Sportabout 18.7 360.0 175 3.15 3.440 17.02 0 0 3 2
Duster 360 14.3 360.0 245 3.21 3.570 15.84 0 0 3 4
Average 20.21 222.21 126.25 3.44 3.09 18.08 0.50 0.38 3.50 2.38

Column Formatting

You can format data in a column by using the various fmt_??? functions:

info_date_style() # View a table with info on date styles

info_time_style() # View a table with info on time styles

info_currencies() # View a table with info on supported currencies

info_locales()    # View a table with info on supported locales

exibble

The exibble dataset is built into gt and has a lot of different formats to demo the specific fmt_??? functions.

dplyr::glimpse(exibble)
Rows: 8
Columns: 9
$ num      <dbl> 1.111e-01, 2.222e+00, 3.333e+01, 4.444e+02, 5.550e+03, NA, 7.…
$ char     <chr> "apricot", "banana", "coconut", "durian", NA, "fig", "grapefr…
$ fctr     <fct> one, two, three, four, five, six, seven, eight
$ date     <chr> "2015-01-15", "2015-02-15", "2015-03-15", "2015-04-15", "2015…
$ time     <chr> "13:35", "14:40", "15:45", "16:50", "17:55", NA, "19:10", "20…
$ datetime <chr> "2018-01-01 02:22", "2018-02-02 14:33", "2018-03-03 03:44", "…
$ currency <dbl> 49.950, 17.950, 1.390, 65100.000, 1325.810, 13.255, NA, 0.440
$ row      <chr> "row_1", "row_2", "row_3", "row_4", "row_5", "row_6", "row_7"…
$ group    <chr> "grp_a", "grp_a", "grp_a", "grp_a", "grp_b", "grp_b", "grp_b"…
exibble %>% 
  gt(rowname_col = "row", groupname_col = "group") %>% 
  fmt_number(columns = vars(num)) %>% 
  fmt_date(columns = vars(date)) %>% 
  fmt_time(columns = vars(time)) %>% 
  fmt_datetime(columns = vars(datetime)) %>% 
  fmt_currency(columns = vars(currency))
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
num char fctr date time datetime currency
grp_a
row_1 0.11 apricot one Thursday, January 15, 2015 13:35 Monday, January 1, 2018 02:22 $49.95
row_2 2.22 banana two Sunday, February 15, 2015 14:40 Friday, February 2, 2018 14:33 $17.95
row_3 33.33 coconut three Sunday, March 15, 2015 15:45 Saturday, March 3, 2018 03:44 $1.39
row_4 444.40 durian four Wednesday, April 15, 2015 16:50 Wednesday, April 4, 2018 15:55 $65,100.00
grp_b
row_5 5,550.00 NA five Friday, May 15, 2015 17:55 Saturday, May 5, 2018 04:00 $1,325.81
row_6 NA fig six Monday, June 15, 2015 NA Wednesday, June 6, 2018 16:11 $13.26
row_7 777,000.00 grapefruit seven NA 19:10 Saturday, July 7, 2018 05:22 NA
row_8 8,880,000.00 honeydew eight Saturday, August 15, 2015 20:20 NA $0.44

To use a specific locale for data formatting, provide specific arguments to the respective functions.

Date formatting

exibble %>% 
  select(date, time, datetime) %>% 
  gt(rowname_col = "row", groupname_col = "group") %>% 
  fmt_date(columns = vars(date), date_style = 3) %>% 
  fmt_time(columns = vars(time), time_style = 5) %>% 
  fmt_datetime(columns = vars(datetime), date_style = 6, time_style = 4)
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
date time datetime
Thu, Jan 15, 2015 1 PM Jan 1, 2018 2:22 AM
Sun, Feb 15, 2015 2 PM Feb 2, 2018 2:33 PM
Sun, Mar 15, 2015 3 PM Mar 3, 2018 3:44 AM
Wed, Apr 15, 2015 4 PM Apr 4, 2018 3:55 PM
Fri, May 15, 2015 5 PM May 5, 2018 4:00 AM
Mon, Jun 15, 2015 NA Jun 6, 2018 4:11 PM
NA 7 PM Jul 7, 2018 5:22 AM
Sat, Aug 15, 2015 8 PM NA

Currency formatting

money <- data.frame(
  USD = c(12.12, 2141.213, 0.42, 1.55, 34414),
  EUR = c(10.68, 1884.27, 0.37, 1.36, 30284.32),
  INR = c(861.07, 152122.48, 29.84, 110, 2444942.63),
  JPY = c(1280, 226144, 44.36, 164, 3634634.61),
  MAD = c(115.78, 20453.94, 4.01, 15, 328739.73)
)

money %>%
  gt() %>%
  fmt_currency(columns = vars(USD), currency = "USD") %>%
  fmt_currency(columns = vars(EUR), currency = "EUR") %>%
  fmt_currency(columns = vars(INR), currency = "INR") %>%
  fmt_currency(columns = vars(JPY), currency = "JPY") %>%
  fmt_currency(columns = vars(MAD), currency = "MAD")
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
USD EUR INR JPY MAD
$12.12 €10.68 ₹861.07 ¥1,280 Dh115.78
$2,141.21 €1,884.27 ₹152,122.48 ¥226,144 Dh20,453.94
$0.42 €0.37 ₹29.84 ¥44 Dh4.01
$1.55 €1.36 ₹110.00 ¥164 Dh15.00
$34,414.00 €30,284.32 ₹2,444,942.63 ¥3,634,635 Dh328,739.73

Percent formatting

data.frame(
  x = 1:5,
  y = 6:10,
  percent = seq(from = 0.1, to =  0.2, by = 0.025)
) %>% 
  gt() %>% 
  fmt_percent(columns = vars(percent), decimals = 1)
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
x y percent
1 6 10.0%
2 7 12.5%
3 8 15.0%
4 9 17.5%
5 10 20.0%

Number formatting

Numeric formatting can include changes to the number of decimals, separators (ie “,”), or even suffixing (ie K, Mb, etc).

exibble %>% 
  select(group, num, currency) %>% 
  gt() %>% 
  fmt_number(columns = vars(num), decimals = 4, sep_mark = "") %>% 
  # Suffixing scale and apply suffixes to larger numbers 
  fmt_number(columns = vars(currency), decimals = 1, suffixing = TRUE)
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
group num currency
grp_a 0.1111 50.0
grp_a 2.2220 17.9
grp_a 33.3300 1.4
grp_a 444.4000 65.1K
grp_b 5550.0000 1.3K
grp_b NA 13.3
grp_b 777000.0000 NA
grp_b 8880000.0000 0.4

Displaying missing values

Missing values are ignored by formatters and shown as NA by default. You can specify missing values with other indicators with fmt_missing

exibble %>% 
  select(group, currency, num) %>% 
  gt() %>% 
  fmt_missing(columns = vars(currency), rows = is.na(currency)) %>% 
  fmt_missing(columns = vars(num), rows = is.na(num), missing_text = "none")
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
group currency num
grp_a 49.950 1.111e-01
grp_a 17.950 2.222e+00
grp_a 1.390 3.333e+01
grp_a 65100.000 4.444e+02
grp_b 1325.810 5.550e+03
grp_b 13.255 none
grp_b 7.770e+05
grp_b 0.440 8.880e+06

Format markdown

You can also parse cell content that contains arbitrary markdown.

# Create a few Markdown-based
# text snippets
text_1a <- "
### This is Markdown.

Markdown’s syntax is comprised entirely of
punctuation characters, which punctuation
characters have been carefully chosen so as
to look like what they mean... assuming
you’ve ever used email.
"

text_1b <- "
Info on Markdown syntax can be found
[here](https://daringfireball.net/projects/markdown/).
"

text_2a <- "
The **gt** package has these datasets:

 - `countrypops`
 - `sza`
 - `gtcars`
 - `sp500`
 - `pizzaplace`
 - `exibble`
"

text_2b <- "
There's a quick reference [here](https://commonmark.org/help/).
"

# Arrange the text snippets as a tibble
# using the `dplyr::tribble()` function;
# then, create a gt table and format
# all columns with `fmt_markdown()`
dplyr::tribble(
  ~Markdown, ~md,
  text_1a,   text_2a,
  text_1b,   text_2b,
  ) %>%
  gt() %>%
  fmt_markdown(columns = TRUE) %>%
  tab_options(table.width = px(400))
Warning: `columns = TRUE` has been deprecated in gt 0.3.0:
* please use `columns = everything()` instead
Markdown md

This is Markdown.

Markdown’s syntax is comprised entirely of punctuation characters, which punctuation characters have been carefully chosen so as to look like what they mean... assuming you’ve ever used email.

The gt package has these datasets:

  • countrypops
  • sza
  • gtcars
  • sp500
  • pizzaplace
  • exibble

Info on Markdown syntax can be found here.

There's a quick reference here.

Custom data formatting

If none of the built-in formatters apply to your data, you can use fmt() instead.

data.frame(
  count = c(1L, 2L, 3L, 4L, 5L),
  weight_g = c(150.65, 149.65, 171.28, 142.58, 139.04),
  color = c("green", "yellow", "yellow", "green", "yellow")
) %>% 
  gt() %>% 
  fmt(
    columns = vars(count),
    fns = function(x){ paste(x, "bananas")}
  ) 
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
count weight_g color
1 bananas 150.65 green
2 bananas 149.65 yellow
3 bananas 171.28 yellow
4 bananas 142.58 green
5 bananas 139.04 yellow

Create or Modify Parts

Add a header

data.frame(
  count = c(1L, 2L, 3L, 4L, 5L),
  weight_g = c(150.65, 149.65, 171.28, 142.58, 139.04),
  color = c("green", "yellow", "yellow", "green", "yellow")
) %>% 
  gt() %>% 
  tab_header(
    title = "Number of bananas, weight, and ripeness",
    subtitle = "Bananas sourced in Mar 2021"
    )
Number of bananas, weight, and ripeness
Bananas sourced in Mar 2021
count weight_g color
1 150.65 green
2 149.65 yellow
3 171.28 yellow
4 142.58 green
5 139.04 yellow

Format header

You can parse markdown with md() or HTML with html().

data.frame(
  count = c(1L, 2L, 3L, 4L, 5L),
  weight_g = c(150.65, 149.65, 171.28, 142.58, 139.04),
  color = c("green", "yellow", "yellow", "green", "yellow")
) %>% 
  gt() %>% 
  tab_header(
    title = md("**Number of bananas, weight, and ripeness**"),
    subtitle = html("Bananas sourced in <em><b>Mar 2021<b></em>")
    )
Number of bananas, weight, and ripeness
Bananas sourced in Mar 2021
count weight_g color
1 150.65 green
2 149.65 yellow
3 171.28 yellow
4 142.58 green
5 139.04 yellow

Add spanner column labels

You can create column label “groups” with the tab_spanner() function.

head(gtcars, 8) %>%
  dplyr::select(model:mpg_h, msrp) %>%  
  gt(rowname_col = "model") %>%
  tab_spanner(
    label = "Performance",
    columns = vars(hp, hp_rpm, trq, trq_rpm, mpg_c, mpg_h)
  ) %>% 
  tab_spanner(
    label = "Car Info",
    columns = vars(year, bdy_style, trim)
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
Car Info Performance msrp
year bdy_style trim hp hp_rpm trq trq_rpm mpg_c mpg_h
GT 2017 coupe Base Coupe 647 6250 550 5900 11 18 447000
458 Speciale 2015 coupe Base Coupe 597 9000 398 6000 13 17 291744
458 Spider 2015 convertible Base 562 9000 398 6000 13 17 263553
458 Italia 2014 coupe Base Coupe 562 9000 398 6000 13 17 233509
488 GTB 2016 coupe Base Coupe 661 8000 561 3000 15 22 245400
California 2015 convertible Base Convertible 553 7500 557 4750 16 23 198973
GTC4Lusso 2017 coupe Base Coupe 680 8250 514 5750 12 17 298000
FF 2015 coupe Base Coupe 652 8000 504 6000 11 16 295000

Add spanner delim

For columns that are well formatted, gt can parse the delimiter and “split” the label into its component parts.

head(gtcars, 8) %>%
  dplyr::select(model:trim, mpg_city = mpg_c, mpg_hwy = mpg_h) %>%  
  gt(rowname_col = "model") %>%
  tab_spanner_delim(delim = "_")
year trim mpg
city hwy
GT 2017 Base Coupe 11 18
458 Speciale 2015 Base Coupe 13 17
458 Spider 2015 Base 13 17
458 Italia 2014 Base Coupe 13 17
488 GTB 2016 Base Coupe 15 22
California 2015 Base Convertible 16 23
GTC4Lusso 2017 Base Coupe 12 17
FF 2015 Base Coupe 11 16

Locations

gt usesthe locations argument across many functions to let you tightly customize specific components. These are considered “Helper Functions”, and are further expended in the gt documentation.

Locations is used with the various cells_??? functions like: cells_title, cells_stubhead, cells_column_spanners().

Cell body

For the cells_body(), it includes arguments for columns and rows, allowing you to specify specific columns or even columns + subsets of specific rows based on logicals.

head(gtcars, 8) %>%
  dplyr::select(model:trim, mpg_city = mpg_c, mpg_hwy = mpg_h) %>%  
  gt(rowname_col = "model") %>% 
  tab_style(
    style = cell_text(color = "red"),
    locations = cells_body(
      columns = vars(trim),
      rows = trim == "Base Convertible"
      )
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
year trim mpg_city mpg_hwy
GT 2017 Base Coupe 11 18
458 Speciale 2015 Base Coupe 13 17
458 Spider 2015 Base 13 17
458 Italia 2014 Base Coupe 13 17
488 GTB 2016 Base Coupe 15 22
California 2015 Base Convertible 16 23
GTC4Lusso 2017 Base Coupe 12 17
FF 2015 Base Coupe 11 16

Table title

Table header/title can be affected by cells_title, and it can affect either the title, subtitle or both (default).

head(gtcars, 8) %>%
  dplyr::select(model:trim, mpg_city = mpg_c, mpg_hwy = mpg_h) %>%  
  gt() %>% 
  tab_header(
    title = "These are not efficient cars",
    subtitle = "But they are fast"
    ) %>% 
  tab_style(
    style = cell_text(color = "black", weight = "bold", align = "left"),
    locations = cells_title("title")
  )
These are not efficient cars
But they are fast
model year trim mpg_city mpg_hwy
GT 2017 Base Coupe 11 18
458 Speciale 2015 Base Coupe 13 17
458 Spider 2015 Base 13 17
458 Italia 2014 Base Coupe 13 17
488 GTB 2016 Base Coupe 15 22
California 2015 Base Convertible 16 23
GTC4Lusso 2017 Base Coupe 12 17
FF 2015 Base Coupe 11 16

Table stub

You can affect both the stubhead and the stub rows themselves as well.

head(gtcars, 8) %>%
  dplyr::select(model:trim, mpg_city = mpg_c, mpg_hwy = mpg_h) %>%  
  gt(rowname_col = "model") %>% 
  tab_stubhead("Car Models") %>% 
  tab_style(
    style = list(
      cell_fill("black"),
      cell_text(color = "white", weight = "bold")
      ),
    locations = cells_stubhead()
  ) %>% 
  tab_style(
    style = cell_text(color = "darkgrey", weight = "bold"),
    locations = cells_stub()
  )
Car Models year trim mpg_city mpg_hwy
GT 2017 Base Coupe 11 18
458 Speciale 2015 Base Coupe 13 17
458 Spider 2015 Base 13 17
458 Italia 2014 Base Coupe 13 17
488 GTB 2016 Base Coupe 15 22
California 2015 Base Convertible 16 23
GTC4Lusso 2017 Base Coupe 12 17
FF 2015 Base Coupe 11 16

Row group

Row groups can be further emphasized by changing the background or other styling.

gtcars %>% 
  filter(mfr %in% c("Ferrari", "Porsche")) %>% 
  dplyr::select(mfr, model:trim, mpg_city = mpg_c, mpg_hwy = mpg_h) %>%  
  gt(rowname_col = "model", groupname_col = "mfr") %>% 
  tab_style(
    style = list(
      cell_fill("black"),
      cell_text(color = "white", weight = "bold")
      ),
    locations = cells_row_groups()
  ) %>% 
  tab_style(
    style = cell_text(color = "darkgrey", weight = "bold"),
    locations = cells_stub()
  )
year trim mpg_city mpg_hwy
Ferrari
458 Speciale 2015 Base Coupe 13 17
458 Spider 2015 Base 13 17
458 Italia 2014 Base Coupe 13 17
488 GTB 2016 Base Coupe 15 22
California 2015 Base Convertible 16 23
GTC4Lusso 2017 Base Coupe 12 17
FF 2015 Base Coupe 11 16
F12Berlinetta 2015 Base Coupe 11 16
LaFerrari 2015 Base Coupe 12 16
Porsche
718 Boxster 2017 Base Convertible 21 28
718 Cayman 2017 Base Coupe 20 29
911 2016 Carrera Coupe 20 28
Panamera 2016 Base Sedan 18 28

Group summary

To affect the grouped summary rows (or grand summary rows) you can use cells_summary() or cells_grand_summary().

gtcars %>% 
  dplyr::filter(mfr %in% c("Ferrari", "Porsche", "Lamborghini")) %>% 
  dplyr::group_by(mfr) %>% 
  dplyr::slice_head(n = 3) %>% 
  dplyr::ungroup() %>% 
  dplyr::select(mfr, model:trim, mpg_city = mpg_c, mpg_hwy = mpg_h) %>%  
  gt(rowname_col = "model", groupname_col = "mfr") %>% 
  gt::summary_rows(
    groups = TRUE, columns = vars(mpg_city, mpg_hwy),
    fns = list(Average = ~mean(.)),
    formatter = fmt_number, decimals = 1
  ) %>% 
  tab_style(
    style = list(
      cell_text(color = "white", font = google_font("Fira Mono")),
      cell_fill("black")
    ),
    locations = cells_summary()
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
year trim mpg_city mpg_hwy
Ferrari
458 Speciale 2015 Base Coupe 13 17
458 Spider 2015 Base 13 17
458 Italia 2014 Base Coupe 13 17
Average 13.0 17.0
Lamborghini
Aventador 2015 LP 700-4 Coupe 11 18
Huracan 2015 LP 610-4 Coupe 16 20
Gallardo 2014 LP 550-2 Coupe 12 20
Average 13.0 19.3
Porsche
718 Boxster 2017 Base Convertible 21 28
718 Cayman 2017 Base Coupe 20 29
911 2016 Carrera Coupe 20 28
Average 20.3 28.3

Spanners and labels

You can also affect the column labels or spanners above the labels. Note the use of a spanner id to make it easy to identify the specific spanner to apply the changes to.

exibble %>%
  dplyr::select(-fctr, -currency, -group) %>%
  gt(rowname_col = "row") %>%
  tab_spanner(
    label = "dates and times",
    id = "dt",
    columns = vars(date, time, datetime)
  ) %>%
  tab_style(
    style = cell_text(color = "darkgrey", transform = "uppercase"),
    locations = cells_column_spanners(spanners = "dt")
  ) %>% 
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels(columns = vars(date, time, datetime))
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
num char dates and times
date time datetime
row_1 1.111e-01 apricot 2015-01-15 13:35 2018-01-01 02:22
row_2 2.222e+00 banana 2015-02-15 14:40 2018-02-02 14:33
row_3 3.333e+01 coconut 2015-03-15 15:45 2018-03-03 03:44
row_4 4.444e+02 durian 2015-04-15 16:50 2018-04-04 15:55
row_5 5.550e+03 NA 2015-05-15 17:55 2018-05-05 04:00
row_6 NA fig 2015-06-15 NA 2018-06-06 16:11
row_7 7.770e+05 grapefruit NA 19:10 2018-07-07 05:22
row_8 8.880e+06 honeydew 2015-08-15 20:20 NA

Add notes

You can also add footnotes or sourcenotes to arbitrary locations within the table. Both will “output” to the bottom of the table, but can place their respective indicators elsewhere.

Add footnote

Footnotes can be added to arbitrary locations with tab_footnote(). Here we add a footnote specifically to the mpg_h column label.

gtcars %>%
  dplyr::select(model, year, trq, mpg_h) %>%
  head(6) %>% 
  gt(rowname_col = "model") %>%
  tab_footnote(
    locations = cells_column_labels(vars(mpg_h)),
    footnote = "Miles per Gallon on Highway"
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
year trq mpg_h1
GT 2017 550 18
458 Speciale 2015 398 17
458 Spider 2015 398 17
458 Italia 2014 398 17
488 GTB 2016 561 22
California 2015 557 23
1 Miles per Gallon on Highway

The location argument allows for other areas to be specified, and the footnote argument can also parse markdown/HTML with the md() and html() helpers.

gtcars %>%
  dplyr::select(model, year, trq, mpg_h) %>%
  head(6) %>% 
  gt(rowname_col = "model") %>%
  tab_footnote(
    locations = cells_stub(rows = c(2,3,6)),
    footnote = md("Manufacturing was interruped for these cars in **2015**")
  )
year trq mpg_h
GT 2017 550 18
458 Speciale1 2015 398 17
458 Spider1 2015 398 17
458 Italia 2014 398 17
488 GTB 2016 561 22
California1 2015 557 23
1 Manufacturing was interruped for these cars in 2015

Add a source note

Source notes, like “data sourced from…” can be added with tab_source_note(), and again it can parse arbitrary HTML or md.

source_tag <- "Data from <a href='https://www.edmunds.com'>Edmunds.com</a>"

gtcars %>%
  dplyr::select(model, year, trq, mpg_h) %>%
  head(6) %>% 
  gt(rowname_col = "model") %>% 
  tab_source_note(html(source_tag))
year trq mpg_h
GT 2017 550 18
458 Speciale 2015 398 17
458 Spider 2015 398 17
458 Italia 2014 398 17
488 GTB 2016 561 22
California 2015 557 23
Data from Edmunds.com

Conditional styling

You can transform specific portions of the table based on conditional logic.

Example conditionals include:

base:ifelse()
dplyr::if_else()
dplyr::case_when()

Text transform

You can change specific text based on a function with text_transform(). This is extremely powerful, but specific to only the column being transformed.

data.frame(
  count = c(1L, 2L, 3L, 4L, 5L),
  weight_g = c(150.65, 149.65, 171.28, 142.58, 139.04),
  color = c("green", "yellow", "yellow", "green", "yellow")
) %>% 
  gt() %>% 
  text_transform(
    locations = cells_body(
      columns = vars(weight_g)),
    fn = function(x) {
      paste0(
        x, " (",
        dplyr::case_when(
          x > 150   ~ "large",
          x <= 150  ~ "small"),
        ")")
    }
  ) 
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
count weight_g color
1 150.65 (large) green
2 149.65 (small) yellow
3 171.28 (large) yellow
4 142.58 (small) green
5 139.04 (small) yellow

Formatting changes

You can logically match to rows and apply specific styling to them such as color.

stocks <- data.frame(
  Symbol = c("GOOG", "FB", "AMZN", "NFLX", "TSLA"),
  Price = c(1265.13, 187.89, 1761.33, 276.82, 328.13),
  Change = c(4.14, 1.51, -19.45, 5.32, -12.45)
)
stocks %>% 
  gt() %>% 
  tab_style(
    style = cell_text(color = "red", weight = "bold"),
    locations = cells_body(
      columns = vars(Change),
      rows = Change < 0
    )
  ) %>% 
  tab_style(
    style = cell_text(color = "blue", weight = "bold"),
    locations = cells_body(
      columns = vars(Change),
      rows = Change >= 0
    )
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
Symbol Price Change
GOOG 1265.13 4.14
FB 187.89 1.51
AMZN 1761.33 -19.45
NFLX 276.82 5.32
TSLA 328.13 -12.45

Style the table

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().

At present this function is focused on the application of styles for HTML output only (as such, other output formats will ignore all tab_style() calls). Using the aforementioned helper functions, here are some of the styles we can apply:

  • the background color of the cell (cell_fill(): color)

  • the cell’s text color, font, and size (cell_text(): color, font, size)

  • the text style (cell_text(): style), enabling the use of italics or oblique text.

  • the text weight (cell_text(): weight), allowing the use of thin to bold text (the degree of choice is greater with variable fonts)

  • the alignment and indentation of text (cell_text(): align and indent)

  • the cell borders (cell_borders())

data.frame(
  count = c(1L, 2L, 3L, 4L, 5L),
  weight_g = c(150.65, 149.65, 171.28, 142.58, 139.04),
  color = c("green", "yellow", "yellow", "green", "yellow")
) %>% 
  gt() %>% 
  tab_style(
    style = list(
      cell_fill(color = "lightgrey"),
      "font-variant: small-caps;"
    ),
    locations = cells_body(columns = vars(color))
  ) %>% 
  tab_style(
    style = list(
      cell_text(color = "green")
    ),
    locations = cells_body(
      columns = vars(color),
      # conditional logic
      rows = color == "green"
    )
  ) %>% 
  tab_style(
    style = list(
      cell_text(color = "goldenrod")
    ),
    locations = cells_body(
      columns = vars(color),
      # conditional logic
      rows = color == "yellow"
    )
  ) %>% 
  tab_style(
    style = list(
      cell_borders(sides = "right", color = "black", weight = px(3))
    ),
    locations = cells_body(
      # entire column
      columns = vars(weight_g)
    )
  ) %>% 
  tab_style(
    style = list(
      cell_text(transform = "uppercase", weight = "bold")
    ),
    # different location
    locations = cells_column_labels(everything())
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
count weight_g color
1 150.65 green
2 149.65 yellow
3 171.28 yellow
4 142.58 green
5 139.04 yellow

Modify Columns

Column labels

The cols_label() function provides the flexibility to relabel one or more columns and we even have the option to use the md() or html() helper functions for rendering column labels from Markdown or using HTML.

head(mtcars) %>% 
  gt() %>% 
  cols_label(
    mpg = "Miles/Gal",
    cyl = "Cylinders"
  )
Miles/Gal Cylinders disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Relabel with markdown or HTML

You can also parse markdown with md() or HTML with html() within the label string.

head(mtcars) %>% 
  gt() %>% 
  cols_label(
    mpg = md("**Miles/Gal**"),       # recognizes markdown syntax
    cyl = html("<em>Cylinders</em>") # recognizes HTML syntax
  )
Miles/Gal Cylinders disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Column Alignment

The individual alignments of columns (which includes the column labels and all of their data cells) can be modified. We have the option to align text to the left, the center, and the right.

For this example we’ve also included all the table lines to “show” the alignment a bit better.

countrypops %>%
  dplyr::select(-contains("code")) %>%
  dplyr::filter(country_name == "Mongolia") %>%
  tail(5) %>%
  gt() %>%
  cols_align(
    align = "left",
    columns = vars(country_name)
  ) %>% 
  cols_align(
    align = "center",
    columns = vars(year)
  ) %>% 
  cols_align(
    align = "right",
    columns = vars(population)
  ) %>% 
  tab_options(table.width = px(300)) %>% 
  opt_table_lines()
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
country_name year population
Mongolia 2013 2869107
Mongolia 2014 2923896
Mongolia 2015 2976877
Mongolia 2016 3027398
Mongolia 2017 3075647

Optimal alignment

Typically, the best practice is to use left-align for text of variable length and right-align for numeric values. The reasoning can be highlighted in the table below. We want to align numeric values on the same scale so that they can be compared on the same scale, whereas text is more easily readable left-aligned. Center-align can be used with strings or values of equal-length.

Note that fmt_number and other fmt_??? applied to numeric will automatically right-align, but text will default to left-align.

gt::exibble %>% 
  select(group, char, num, currency) %>% 
  gt() %>% 
  cols_align(align = "center", columns = vars(group)) %>% 
  fmt_number(columns = vars(num)) %>% 
  fmt_currency(columns = vars(currency))
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
group char num currency
grp_a apricot 0.11 $49.95
grp_a banana 2.22 $17.95
grp_a coconut 33.33 $1.39
grp_a durian 444.40 $65,100.00
grp_b NA 5,550.00 $1,325.81
grp_b fig NA $13.26
grp_b grapefruit 777,000.00 NA
grp_b honeydew 8,880,000.00 $0.44

Column Width

We choose which columns get specific widths. This can be in units of pixels (easily set by use of the px() helper function), or, as percentages (where the pct() helper function is useful).

countrypops %>%
  dplyr::select(-contains("code")) %>%
  dplyr::filter(country_name == "Mongolia") %>%
  tail(5) %>%
  gt() %>% 
  cols_width(
    vars(country_name) ~ px(200),
    vars(year) ~ px(50),
    vars(population) ~ px(100)
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
country_name year population
Mongolia 2013 2869107
Mongolia 2014 2923896
Mongolia 2015 2976877
Mongolia 2016 3027398
Mongolia 2017 3075647

Change all columns

You can use the everything() function to affect all columns (or remaining columns).

mtcars %>% 
  tibble::rownames_to_column("names") %>% 
  head(8) %>%
  gt() %>% 
  cols_width(
    vars(names) ~ px(150),
    everything() ~ px(60)
  ) %>% 
  opt_table_lines()
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
names mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2

Move columns

You can move columns to the beginning, end, or arbitrary locations.

To start

countrypops %>% 
  dplyr::select(country_name, year:population) %>% 
  tail(8) %>% 
  gt() %>% 
  cols_move_to_start(vars(year))
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
year country_name population
2010 Zimbabwe 14086317
2011 Zimbabwe 14386649
2012 Zimbabwe 14710826
2013 Zimbabwe 15054506
2014 Zimbabwe 15411675
2015 Zimbabwe 15777451
2016 Zimbabwe 16150362
2017 Zimbabwe 16529904

To end

countrypops %>% 
  dplyr::select(country_name, year:population) %>% 
  tail(8) %>% 
  gt() %>% 
  cols_move_to_end(vars(year))
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
country_name population year
Zimbabwe 14086317 2010
Zimbabwe 14386649 2011
Zimbabwe 14710826 2012
Zimbabwe 15054506 2013
Zimbabwe 15411675 2014
Zimbabwe 15777451 2015
Zimbabwe 16150362 2016
Zimbabwe 16529904 2017

Wherever you want

countrypops %>% 
  dplyr::select(country_name, year:population) %>% 
  tail(8) %>% 
  gt() %>% 
  cols_move(
    columns = vars(country_name),
    after = vars(year)
    )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
year country_name population
2010 Zimbabwe 14086317
2011 Zimbabwe 14386649
2012 Zimbabwe 14710826
2013 Zimbabwe 15054506
2014 Zimbabwe 15411675
2015 Zimbabwe 15777451
2016 Zimbabwe 16150362
2017 Zimbabwe 16529904

Hide columns

You can also hide arbitrary columns, but still reference them inside gt.

zim_code <- unique(countrypops$country_code_2) %>% .[length(.)]
countrypops %>% 
  tail(8) %>% 
  gt() %>% 
  cols_hide(columns = dplyr::contains("code")) %>% 
  tab_footnote(
    footnote = paste("The country code is", zim_code),
    locations = cells_body(
      columns = vars(country_name),
      rows = country_code_2 == zim_code
    )
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
country_name year population
Zimbabwe1 2010 14086317
Zimbabwe1 2011 14386649
Zimbabwe1 2012 14710826
Zimbabwe1 2013 15054506
Zimbabwe1 2014 15411675
Zimbabwe1 2015 15777451
Zimbabwe1 2016 16150362
Zimbabwe1 2017 16529904
1 The country code is ZW

Merge columns

Columns can be merged with glue-like syntax.

sp500 %>%
  dplyr::slice(50:55) %>%
  dplyr::select(-volume, -adj_close) %>%
  gt() %>%
  cols_merge(
    columns = vars(open, close),
    hide_columns = vars(close),
    pattern = "{1}&mdash;{2}"
  ) %>%
  cols_merge(
    columns = vars(low, high),
    hide_columns = vars(high),
    pattern = "{1}&mdash;{2}"
  ) %>%
  cols_label(
    open = "open/close",
    low = "low/high"
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
date open/close low/high
2015-10-21 2033.47—2018.94 2017.22—2037.97
2015-10-20 2033.13—2030.77 2026.61—2039.12
2015-10-19 2031.73—2033.66 2022.31—2034.45
2015-10-16 2024.37—2033.11 2020.46—2033.54
2015-10-15 1996.47—2023.86 1996.47—2024.15
2015-10-14 2003.66—1994.24 1990.73—2009.56

Table Customization

You can customize table “theme” using several options, which can all be combined:

Bordered

head(mtcars) %>% 
  gt() %>% 
  opt_table_lines("all")
mpg cyl disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Borderless

head(mtcars) %>% 
  gt() %>% 
  opt_table_lines("none")
mpg cyl disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Outlined

mpg cyl disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Striped

mpg cyl disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Add dividers

You can specify locations to add borders/dividers and control the weight/color/side of the border.

head(mtcars) %>% 
  gt() %>% 
  tab_style(
    style = cell_borders(sides = "right", color = "black", 
                         style = "dashed", weight = px(3)),
    locations = cells_body(
      columns = vars(cyl)
    )
  ) %>% 
  tab_style(
    style = cell_borders(sides = "bottom", color = "black", weight = px(3)),
    locations = cells_column_labels(everything())
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
mpg cyl disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

You can also include locations outside of the cell body, ie the column labels or other locations.

head(mtcars) %>% 
  dplyr::select(cyl, everything()) %>% 
  gt() %>% 
  opt_table_lines("none") %>% 
  opt_row_striping() %>% 
  tab_style(
    style = cell_borders(sides = "right", color = "black", weight = px(3)),
    locations = cells_body(
      columns = vars(cyl)
    )
  ) %>% 
  tab_style(
    style = cell_borders(sides = c("top", "bottom"), 
                         color = "black", weight = px(3)),
    locations = cells_column_labels(everything())
  ) %>% 
  tab_style(
    style = cell_borders(sides = "bottom", color = "black", weight = px(3)),
    locations = cells_body(rows = 6)
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
cyl mpg disp hp drat wt qsec vs am gear carb
6 21.0 160 110 3.90 2.620 16.46 0 1 4 4
6 21.0 160 110 3.90 2.875 17.02 0 1 4 4
4 22.8 108 93 3.85 2.320 18.61 1 1 4 1
6 21.4 258 110 3.08 3.215 19.44 1 0 3 1
8 18.7 360 175 3.15 3.440 17.02 0 0 3 2
6 18.1 225 105 2.76 3.460 20.22 1 0 3 1

Adjust fonts

You can use system fonts or bring in Google fonts with google_font().

# change font for entire table
head(mtcars) %>% 
  dplyr::select(cyl, everything()) %>% 
  gt() %>% 
  opt_table_font(font = google_font("Fira Mono"))
cyl mpg disp hp drat wt qsec vs am gear carb
6 21.0 160 110 3.90 2.620 16.46 0 1 4 4
6 21.0 160 110 3.90 2.875 17.02 0 1 4 4
4 22.8 108 93 3.85 2.320 18.61 1 1 4 1
6 21.4 258 110 3.08 3.215 19.44 1 0 3 1
8 18.7 360 175 3.15 3.440 17.02 0 0 3 2
6 18.1 225 105 2.76 3.460 20.22 1 0 3 1

Fonts by location

Adjusting font by location can be done via tab_style().

head(mtcars) %>% 
  dplyr::select(cyl, everything()) %>% 
  gt() %>% 
  # change cell body font
  tab_style(
    style = cell_text(
      font = google_font("Fira Mono"), size = px(14)),
    locations = cells_body(columns = everything())
  ) %>% 
  # change column labels
  tab_style(
    style = cell_text(
      font = google_font("Indie Flower"), 
      weight = "bold",
      size = px(30)
      ),
    locations = cells_column_labels(everything())
  )
cyl mpg disp hp drat wt qsec vs am gear carb
6 21.0 160 110 3.90 2.620 16.46 0 1 4 4
6 21.0 160 110 3.90 2.875 17.02 0 1 4 4
4 22.8 108 93 3.85 2.320 18.61 1 1 4 1
6 21.4 258 110 3.08 3.215 19.44 1 0 3 1
8 18.7 360 175 3.15 3.440 17.02 0 0 3 2
6 18.1 225 105 2.76 3.460 20.22 1 0 3 1

And the changes can be made outside of just the body of the table, for example the title/header.

countrypops %>%
  dplyr::select(-contains("code")) %>%
  tail(5) %>%
  gt() %>% 
  tab_style(
    style = cell_text(font = google_font("Fira Mono")),
    locations = cells_body(columns = vars(year, population))
  ) %>% 
  tab_style(
    style = cell_text(font = google_font("Raleway"), weight = "bold"),
    locations = cells_body(columns = vars(country_name))
  ) %>% 
  tab_style(
    style = cell_text(
      font = google_font("Indie Flower"), 
      weight = "bold", 
      align = "left",
      size = px(40)
      ),
    locations = cells_title("title")
  ) %>% 
  tab_header("Population changes")
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead

Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
Population changes
country_name year population
Zimbabwe 2013 15054506
Zimbabwe 2014 15411675
Zimbabwe 2015 15777451
Zimbabwe 2016 16150362
Zimbabwe 2017 16529904

Table options

Modify the options available in a table. These options are named by the components, the subcomponents, and the element that can adjusted.

This is where the bulk of theme-changes can be done. tab_options has dozens of different table components that can be adjusted. The full details can be found in the {gt} documentation. You can customize all sorts of arbitrary components based globally.

head(mtcars) %>% 
  gt() %>% 
  tab_options(
    table.background.color = "black",
    column_labels.background.color = "grey",
    column_labels.font.size = px(16),
    table.font.size = px(12),
    data_row.padding = px(4),
    table.width = px(250)
  )
mpg cyl disp hp drat wt qsec vs am gear carb
21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Conditional formatting

Color scales

To add color scales, you can use R’s built-in color utilities (or other color manipulation packages like {paletteer}):

Conditional coloring

It’s possible to add color to data cells according to their values. The data_color() function colors all rows of any columns supplied. There are two ways to define how cells are colored: (1) through the use of a supplied color palette, and (2) through use of a color mapping function available from the {scales} package. The first method colorizes cell data according to whether values are character or numeric. The second method provides more control over how cells are colored since we provide an explicit color function and thus other requirements such as bin counts, cut points, or a numeric domain.

countrypops %>%
  dplyr::filter(country_name == "Mongolia") %>%
  dplyr::select(-contains("code")) %>%
  tail(10) %>%
  gt() %>%
  data_color(
    columns = vars(population),
    colors = scales::col_numeric(
      palette = c(
        "white", "orange", "red"),
      domain = NULL)
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
country_name year population
Mongolia 2008 2628131
Mongolia 2009 2668289
Mongolia 2010 2712650
Mongolia 2011 2761516
Mongolia 2012 2814226
Mongolia 2013 2869107
Mongolia 2014 2923896
Mongolia 2015 2976877
Mongolia 2016 3027398
Mongolia 2017 3075647


Factors

Factors are typically more appropriate with qualitative palettes, and we can use scales::col_factor() to apply colors to the specific column of interest. Note that the color palette needs to be equal to the unique number of factors. In the example below we pass n = 3 since we have 3 different trim types.

gtcars %>% 
  dplyr::filter(mfr == "Ferrari", hp < 900) %>% 
  dplyr::select(model, hp, trim, mpg_h, msrp) %>% 
  gt() %>% 
  data_color(
    columns = vars(trim),
    colors = scales::col_factor(
      palette = paletteer::paletteer_d(
        n = 3, palette = "colorblindr::OkabeIto"
        ) %>% as.character(),
      domain = NULL
      )
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
model hp trim mpg_h msrp
458 Speciale 597 Base Coupe 17 291744
458 Spider 562 Base 17 263553
458 Italia 562 Base Coupe 17 233509
488 GTB 661 Base Coupe 22 245400
California 553 Base Convertible 23 198973
GTC4Lusso 680 Base Coupe 17 298000
FF 652 Base Coupe 16 295000
F12Berlinetta 731 Base Coupe 16 319995


Multiple columns

This can also be applied across multiple columns at once. Here’s an example using the built in nottem dataset. While red-green color scales are very commonly used, they are not color-blind friendly.

We can alternatively use something like red-white-blue, or purple-white-green.

dimnames <- list(start(nottem)[1]:end(nottem)[1], month.abb)
temps <- matrix(nottem, ncol = 12, byrow = TRUE, dimnames = dimnames) %>% 
  data.frame() %>% 
  tibble::rownames_to_column() %>% 
  head(10)

temps %>% 
  gt() %>% 
  data_color(
    columns = vars(month.abb),
    colors = scales::col_numeric(
      c("#63be7b", "#ffeb84", "#f87274"), 
      domain = range(nottem))
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
Note: Using an external vector in selections is ambiguous.
ℹ Use `all_of(month.abb)` instead of `month.abb` to silence this message.
ℹ See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
This message is displayed once per session.
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1920 40.6 40.8 44.4 46.7 54.1 58.5 57.7 56.4 54.3 50.5 42.9 39.8
1921 44.2 39.8 45.1 47.0 54.1 58.7 66.3 59.9 57.0 54.2 39.7 42.8
1922 37.5 38.7 39.5 42.1 55.7 57.8 56.8 54.3 54.3 47.1 41.8 41.7
1923 41.8 40.1 42.9 45.8 49.2 52.7 64.2 59.6 54.4 49.2 36.3 37.6
1924 39.3 37.5 38.3 45.5 53.2 57.7 60.8 58.2 56.4 49.8 44.4 43.6
1925 40.0 40.5 40.8 45.1 53.8 59.4 63.5 61.0 53.0 50.0 38.1 36.3
1926 39.2 43.4 43.4 48.9 50.6 56.8 62.5 62.0 57.5 46.7 41.6 39.8
1927 39.4 38.5 45.3 47.1 51.7 55.0 60.4 60.5 54.7 50.3 42.3 35.2
1928 40.8 41.1 42.8 47.3 50.9 56.4 62.2 60.5 55.4 50.2 43.0 37.3
1929 34.8 31.3 41.0 43.9 53.1 56.9 62.5 60.3 59.8 49.2 42.9 41.9

“Hulk” Colors

temps %>% 
  gt() %>% 
  data_color(
    columns = vars(month.abb),
    colors = scales::col_numeric(
      colorspace::diverge_hcl(n = 9, palette = "Purple-Green") %>% rev(), 
      domain = range(nottem))
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1920 40.6 40.8 44.4 46.7 54.1 58.5 57.7 56.4 54.3 50.5 42.9 39.8
1921 44.2 39.8 45.1 47.0 54.1 58.7 66.3 59.9 57.0 54.2 39.7 42.8
1922 37.5 38.7 39.5 42.1 55.7 57.8 56.8 54.3 54.3 47.1 41.8 41.7
1923 41.8 40.1 42.9 45.8 49.2 52.7 64.2 59.6 54.4 49.2 36.3 37.6
1924 39.3 37.5 38.3 45.5 53.2 57.7 60.8 58.2 56.4 49.8 44.4 43.6
1925 40.0 40.5 40.8 45.1 53.8 59.4 63.5 61.0 53.0 50.0 38.1 36.3
1926 39.2 43.4 43.4 48.9 50.6 56.8 62.5 62.0 57.5 46.7 41.6 39.8
1927 39.4 38.5 45.3 47.1 51.7 55.0 60.4 60.5 54.7 50.3 42.3 35.2
1928 40.8 41.1 42.8 47.3 50.9 56.4 62.2 60.5 55.4 50.2 43.0 37.3
1929 34.8 31.3 41.0 43.9 53.1 56.9 62.5 60.3 59.8 49.2 42.9 41.9

Red blue palette

temps %>% 
  gt() %>% 
  data_color(
    columns = vars(month.abb),
    colors = scales::col_numeric(
      colorspace::diverge_hcl(n = 9, palette = "Blue-Red 3"), 
      domain = range(nottem))
  )
Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
* please use `columns = c(...)` instead