All gt tables begin with a call to gt(), where we would supply the input data table (data frame or tibble) and some basic options for creating a stub (rowname_col) and row groups (groupname_col). We can also introduce a grouped tibble (via dplyr’s group_by()) for more precise divisions of rows into row groups.
The gt_preview() function is great for getting a nicely-formatted preview of a data table (defaulting to the first 5 rows and the last row).
Finally, sometimes we want to export the table to some format. It could be HTML, it could be RTF… whichever you go with, you can use the gtsave() function.
gt()gt_preview()gtsave()gt(): Create a gt table objectgt(
data,
rowname_col = "rowname",
groupname_col = dplyr::group_vars(data),
caption = NULL,
rownames_to_stub = FALSE,
auto_align = TRUE,
id = NULL,
row_group.sep = getOption("gt.row_group.sep", " - ")
)
The gt() function creates a gt table object when provided with table data. Using this function is the first step in a typical gt workflow. Once we have the gt table object, we can perform styling transformations before rendering to a display table of various formats.
The gt package contains a few datasets:
countrypops - Yearly populations of countries from 1960 to 2017sza - Twice hourly solar zenith angles by month & latitudegtcars - Deluxe automobiles from the 2014-2017 periodsp500 - Daily S&P 500 Index data from 1950 to 2015pizzaplace - A year of pizza sales from a pizza placeexibble - A toy example tibble for testing with gt: exibbleWe will use exibble a lot during this workshop simply because the entire table easily fits on a screen and contains various types of data. It’s perfect for examples.
Let’s print out exibble and see what it looks like:
exibble
## # A tibble: 8 × 9
## num char fctr date time datetime currency row group
## <dbl> <chr> <fct> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 0.111 apricot one 2015-01-15 13:35 2018-01-01… 50.0 row_1 grp_a
## 2 2.22 banana two 2015-02-15 14:40 2018-02-02… 18.0 row_2 grp_a
## 3 33.3 coconut three 2015-03-15 15:45 2018-03-03… 1.39 row_3 grp_a
## 4 444. durian four 2015-04-15 16:50 2018-04-04… 65100 row_4 grp_a
## 5 5550 <NA> five 2015-05-15 17:55 2018-05-05… 1326. row_5 grp_b
## 6 NA fig six 2015-06-15 <NA> 2018-06-06… 13.3 row_6 grp_b
## 7 777000 grapefruit seven <NA> 19:10 2018-07-07… NA row_7 grp_b
## 8 8880000 honeydew eight 2015-08-15 20:20 <NA> 0.44 row_8 grp_b
Now lets introduce exibble to the gt() function.
exibble %>% gt()
| num | char | fctr | date | time | datetime | currency | row | group |
|---|---|---|---|---|---|---|---|---|
| 1.111e-01 | apricot | one | 2015-01-15 | 13:35 | 2018-01-01 02:22 | 49.950 | row_1 | grp_a |
| 2.222e+00 | banana | two | 2015-02-15 | 14:40 | 2018-02-02 14:33 | 17.950 | row_2 | grp_a |
| 3.333e+01 | coconut | three | 2015-03-15 | 15:45 | 2018-03-03 03:44 | 1.390 | row_3 | grp_a |
| 4.444e+02 | durian | four | 2015-04-15 | 16:50 | 2018-04-04 15:55 | 65100.000 | row_4 | grp_a |
| 5.550e+03 | NA | five | 2015-05-15 | 17:55 | 2018-05-05 04:00 | 1325.810 | row_5 | grp_b |
| NA | fig | six | 2015-06-15 | NA | 2018-06-06 16:11 | 13.255 | row_6 | grp_b |
| 7.770e+05 | grapefruit | seven | NA | 19:10 | 2018-07-07 05:22 | NA | row_7 | grp_b |
| 8.880e+06 | honeydew | eight | 2015-08-15 | 20:20 | NA | 0.440 | row_8 | grp_b |
The above is the basic layout, containing the column labels and the body cells. Numbers are minimally formatted (see the num column) but we can apply our own specific formatting (in the next module).
We can modify the layout a bit in the first step and create a stub. A stub is a special column that contains row labels/names. To do this, we supply the name of the column we’d like to use as the stub to the rowname_col argument. Conveniently, we have the "row" column in exibble that’s good for this purpose:
exibble %>% gt(rowname_col = "row")
| num | char | fctr | date | time | datetime | currency | group | |
|---|---|---|---|---|---|---|---|---|
| row_1 | 1.111e-01 | apricot | one | 2015-01-15 | 13:35 | 2018-01-01 02:22 | 49.950 | grp_a |
| row_2 | 2.222e+00 | banana | two | 2015-02-15 | 14:40 | 2018-02-02 14:33 | 17.950 | grp_a |
| row_3 | 3.333e+01 | coconut | three | 2015-03-15 | 15:45 | 2018-03-03 03:44 | 1.390 | grp_a |
| row_4 | 4.444e+02 | durian | four | 2015-04-15 | 16:50 | 2018-04-04 15:55 | 65100.000 | grp_a |
| row_5 | 5.550e+03 | NA | five | 2015-05-15 | 17:55 | 2018-05-05 04:00 | 1325.810 | grp_b |
| row_6 | NA | fig | six | 2015-06-15 | NA | 2018-06-06 16:11 | 13.255 | grp_b |
| row_7 | 7.770e+05 | grapefruit | seven | NA | 19:10 | 2018-07-07 05:22 | NA | grp_b |
| row_8 | 8.880e+06 | honeydew | eight | 2015-08-15 | 20:20 | NA | 0.440 | grp_b |
Great! A bit on the stub. It doesn’t have a column label above it because it’s technically not a column (it’s the… stub). We can still put a label above it though! That’s with the tab_stubhead() function (in the next module).
We can do some more structuring. Sets of rows can be grouped, showing a row group label above each group. We can do this by using a column containing categorical values (usually grouping labels). Conveniently again, exibble has the "group" column. Let’s use that in the rowname_col argument of gt() and see what it looks like:
exibble %>% gt(rowname_col = "row", groupname_col = "group")
| num | char | fctr | date | time | datetime | currency | |
|---|---|---|---|---|---|---|---|
| grp_a | |||||||
| row_1 | 1.111e-01 | apricot | one | 2015-01-15 | 13:35 | 2018-01-01 02:22 | 49.950 |
| row_2 | 2.222e+00 | banana | two | 2015-02-15 | 14:40 | 2018-02-02 14:33 | 17.950 |
| row_3 | 3.333e+01 | coconut | three | 2015-03-15 | 15:45 | 2018-03-03 03:44 | 1.390 |
| row_4 | 4.444e+02 | durian | four | 2015-04-15 | 16:50 | 2018-04-04 15:55 | 65100.000 |
| grp_b | |||||||
| row_5 | 5.550e+03 | NA | five | 2015-05-15 | 17:55 | 2018-05-05 04:00 | 1325.810 |
| row_6 | NA | fig | six | 2015-06-15 | NA | 2018-06-06 16:11 | 13.255 |
| row_7 | 7.770e+05 | grapefruit | seven | NA | 19:10 | 2018-07-07 05:22 | NA |
| row_8 | 8.880e+06 | honeydew | eight | 2015-08-15 | 20:20 | NA | 0.440 |
Even if rows are in a weird order, gt will put the rows in the correct group (but still respect the order of rows).
exibble %>% dplyr::sample_n(size = 8) %>% gt(rowname_col = "row", groupname_col = "group")
| num | char | fctr | date | time | datetime | currency | |
|---|---|---|---|---|---|---|---|
| grp_a | |||||||
| row_1 | 1.111e-01 | apricot | one | 2015-01-15 | 13:35 | 2018-01-01 02:22 | 49.950 |
| row_2 | 2.222e+00 | banana | two | 2015-02-15 | 14:40 | 2018-02-02 14:33 | 17.950 |
| row_3 | 3.333e+01 | coconut | three | 2015-03-15 | 15:45 | 2018-03-03 03:44 | 1.390 |
| row_4 | 4.444e+02 | durian | four | 2015-04-15 | 16:50 | 2018-04-04 15:55 | 65100.000 |
| grp_b | |||||||
| row_8 | 8.880e+06 | honeydew | eight | 2015-08-15 | 20:20 | NA | 0.440 |
| row_7 | 7.770e+05 | grapefruit | seven | NA | 19:10 | 2018-07-07 05:22 | NA |
| row_6 | NA | fig | six | 2015-06-15 | NA | 2018-06-06 16:11 | 13.255 |
| row_5 | 5.550e+03 | NA | five | 2015-05-15 | 17:55 | 2018-05-05 04:00 | 1325.810 |
Say you have a data frame with row names (like mtcars). You can put those row.names in the stub with rownames_to_stub = TRUE:
mtcars %>%
dplyr::slice_head(n = 10) %>%
gt(rownames_to_stub = TRUE)
| 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 |
| Merc 230 | 22.8 | 4 | 140.8 | 95 | 3.92 | 3.150 | 22.90 | 1 | 0 | 4 | 2 |
| Merc 280 | 19.2 | 6 | 167.6 | 123 | 3.92 | 3.440 | 18.30 | 1 | 0 | 4 | 4 |
But if you’re into dplyr you’re probably into group_by()-ing and all that jazz. If you have a grouped tibble, you can pass that into gt() and it’ll know what to do:
exibble %>%
dplyr::group_by(group) %>%
gt(rowname_col = "row")
| num | char | fctr | date | time | datetime | currency | |
|---|---|---|---|---|---|---|---|
| grp_a | |||||||
| row_1 | 1.111e-01 | apricot | one | 2015-01-15 | 13:35 | 2018-01-01 02:22 | 49.950 |
| row_2 | 2.222e+00 | banana | two | 2015-02-15 | 14:40 | 2018-02-02 14:33 | 17.950 |
| row_3 | 3.333e+01 | coconut | three | 2015-03-15 | 15:45 | 2018-03-03 03:44 | 1.390 |
| row_4 | 4.444e+02 | durian | four | 2015-04-15 | 16:50 | 2018-04-04 15:55 | 65100.000 |
| grp_b | |||||||
| row_5 | 5.550e+03 | NA | five | 2015-05-15 | 17:55 | 2018-05-05 04:00 | 1325.810 |
| row_6 | NA | fig | six | 2015-06-15 | NA | 2018-06-06 16:11 | 13.255 |
| row_7 | 7.770e+05 | grapefruit | seven | NA | 19:10 | 2018-07-07 05:22 | NA |
| row_8 | 8.880e+06 | honeydew | eight | 2015-08-15 | 20:20 | NA | 0.440 |
This also works if you have multiple columns grouped. Use row_group.sep to specify the separator between labels.
pizzaplace %>%
dplyr::filter(type %in% c("supreme", "veggie")) %>%
dplyr::group_by(type, size) %>%
dplyr::slice_head(n = 3) %>%
gt(row_group.sep = " // ")
| id | date | time | name | price |
|---|---|---|---|---|
| supreme // L | ||||
| 2015-000002 | 2015-01-01 | 11:57:40 | ital_supr | 20.75 |
| 2015-000003 | 2015-01-01 | 12:12:28 | prsc_argla | 20.75 |
| 2015-000009 | 2015-01-01 | 12:52:01 | ital_supr | 20.75 |
| supreme // M | ||||
| 2015-000003 | 2015-01-01 | 12:12:28 | ital_supr | 16.50 |
| 2015-000004 | 2015-01-01 | 12:16:31 | ital_supr | 16.50 |
| 2015-000005 | 2015-01-01 | 12:21:30 | ital_supr | 16.50 |
| supreme // S | ||||
| 2015-000007 | 2015-01-01 | 12:50:37 | spinach_supr | 12.50 |
| 2015-000008 | 2015-01-01 | 12:51:37 | spinach_supr | 12.50 |
| 2015-000009 | 2015-01-01 | 12:52:01 | ital_supr | 12.50 |
| veggie // L | ||||
| 2015-000002 | 2015-01-01 | 11:57:40 | five_cheese | 18.50 |
| 2015-000009 | 2015-01-01 | 12:52:01 | spin_pesto | 20.75 |
| 2015-000010 | 2015-01-01 | 13:00:15 | mexicana | 20.25 |
| veggie // M | ||||
| 2015-000002 | 2015-01-01 | 11:57:40 | mexicana | 16.00 |
| 2015-000017 | 2015-01-01 | 13:53:00 | mediterraneo | 16.00 |
| 2015-000017 | 2015-01-01 | 13:53:00 | four_cheese | 14.75 |
| veggie // S | ||||
| 2015-000009 | 2015-01-01 | 12:52:01 | mexicana | 12.00 |
| 2015-000009 | 2015-01-01 | 12:52:01 | veggie_veg | 12.00 |
| 2015-000009 | 2015-01-01 | 12:52:01 | green_garden | 12.00 |
gt_preview(): Preview a gt table objectgt_preview(
data,
top_n = 5,
bottom_n = 1,
incl_rownums = TRUE
)
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).
Use gtcars to create a gt table preview (with only a few of its columns). You’ll see the first five rows and the last row.
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 |
Don’t want to see the row numbers? That’s fine, use incl_rownums = FALSE.
sp500 %>%
gt_preview(
bottom_n = 5,
incl_rownums = FALSE
)
| date | open | high | low | close | volume | adj_close |
|---|---|---|---|---|---|---|
| 2015-12-31 | 2060.59 | 2062.54 | 2043.62 | 2043.94 | 2655330000 | 2043.94 |
| 2015-12-30 | 2077.34 | 2077.34 | 2061.97 | 2063.36 | 2367430000 | 2063.36 |
| 2015-12-29 | 2060.54 | 2081.56 | 2060.54 | 2078.36 | 2542000000 | 2078.36 |
| 2015-12-28 | 2057.77 | 2057.77 | 2044.20 | 2056.50 | 2492510000 | 2056.50 |
| 2015-12-24 | 2063.52 | 2067.36 | 2058.73 | 2060.99 | 1411860000 | 2060.99 |
| 1950-01-09 | 17.08 | 17.08 | 17.08 | 17.08 | 2520000 | 17.08 |
| 1950-01-06 | 16.98 | 16.98 | 16.98 | 16.98 | 2010000 | 16.98 |
| 1950-01-05 | 16.93 | 16.93 | 16.93 | 16.93 | 2550000 | 16.93 |
| 1950-01-04 | 16.85 | 16.85 | 16.85 | 16.85 | 1890000 | 16.85 |
| 1950-01-03 | 16.66 | 16.66 | 16.66 | 16.66 | 1260000 | 16.66 |
gtsave(): Save a gt table as a filegtsave(
data,
filename,
path = NULL,
...
)
The gtsave() function makes it easy to save a gt table to a file. The function assumes the output file type by the extension provided in the output filename. This will produce either an HTML, PDF, PNG, LaTeX, or RTF file.
Use exibble to create a gt table.
gt_tbl <-
exibble %>%
gt(
rowname_col = "row",
groupname_col = "group"
)
Get an HTML file with inlined CSS (which is necessary for including the table as part of an HTML email in the blastula package).
#gt_tbl %>% gtsave("tab_1_inlined.html", inline_css = TRUE)
By leaving out the inline_css option, we get a more conventional HTML file with embedded CSS styles.
#gt_tbl %>% gtsave("tab_1.html")
Get an RTF file by using the .rtf extension in the filename.
#gt_tbl %>% gtsave("tab_r.rtf")
Get a PNG file (essentially a screenshot of the HTML table) by using the .png extension.
#gt_tbl %>% gtsave("tab_r.png")
Get a LaTeX table fragment by using the .ltx extension.
#gt_tbl %>% gtsave("tab_r.ltx")
If you know about LaTeX, you’ll know that you generally need LaTeX packages and gt_latex_dependencies() gives us the names of the packages that gt needs.
#gt::gt_latex_dependencies() %>% cat()
gt().gt() function has a few options for adding group rows and a stub.gt_preview()gtsave(); trick is to name the file in a supported format (e.g., "gt_table.rtf" for an RTF file containing the table).