flextable - A very useful package for Word-based table
2 Preliminaries
2.1 Packages
As always, the first port of call is to bring in the packages we need for this session.
library(gt) # Grammar of tables
Warning: package 'gt' was built under R version 4.4.2
library(tidyverse) # Data Manipulation
Warning: package 'tidyverse' was built under R version 4.4.2
Warning: package 'ggplot2' was built under R version 4.4.2
Warning: package 'tidyr' was built under R version 4.4.2
Warning: package 'readr' was built under R version 4.4.2
Warning: package 'purrr' was built under R version 4.4.2
Warning: package 'stringr' was built under R version 4.4.2
Warning: package 'forcats' was built under R version 4.4.2
Warning: package 'lubridate' was built under R version 4.4.2
library(janitor) # Clean names
Warning: package 'janitor' was built under R version 4.4.2
2.2 Data
Next is to read in the dataset that we will use, which is the same as we have used in previous chapters, the gapminder data. We will clean column names with janitor and drop the NA values as we have done previously.
# Importing data using the read_csv function gapminder <-read_csv("./data/gapminder.csv")# Cleaning column names using the clean_names function# Dropping missing values using the drop_na function gapminder <-clean_names(gapminder) |>drop_na()
The goal of gt is similar to that of ggplot2, is to make it easy to produce nice-looking display tables. e.g. summary tables, presentation tables.
This is a recent package been released in March 2020, developed by Richard Iannone.
It was designed to mirror the layered style of creating ggplot2 figures.
If you need to make beautiful customized tables then gt is great choice. There are so many ways to structure a table, apply formatting and annotations, and style it just the way you want.
Currently gt renders tables to the HTML output format (and has the ability to export to image files).
If your primary output is model summaries rather than data tables, make sure to check out the wonderful gt summary R package which extends the gt package for statistical model summaries.
Features of a table
Image taken from: (https://github.com/laRusers/presentations/blob/master/2020-05-27-rich-avik/gt_talk_la_r_users-rich_i.pdf).
3.1 Parts of a gt table
The table has the components shown in the image below, within each of these components, there may be sub components. e.g. the table header contains a title and subtitle
Image taken from: (https://gt.rstudio.com/articles/intro-creating-gt-tables.html).
Table Header - contains a title and subtitle
Stub and the Stub Head - contains row labels
Column Labels - contains column labels
Table Body -contains columns and rows of cells
Table Footer - footnotes and source notes
3.2 Creating a Basic Table
lets first of all get our data ready, we will continue using the gapminder data.
# Data manipulationpopulation_for_select_countries_3y <- gapminder |>filter(year %in%c(1997, 2002, 2007)) |>select(country, continent, year, pop) |># Reshaping the data tidyr::pivot_wider(names_from = year, values_from = pop) |> tidyr::drop_na() |>group_by(continent) |># Selecting the top 2 values dplyr::top_n(n =2)
Selecting by 2007
# Cleaning the column namespopulation_for_select_countries_3y <- janitor::clean_names(population_for_select_countries_3y)# To Display the datapopulation_for_select_countries_3y
# A tibble: 10 × 5
# Groups: continent [5]
country continent x1997 x2002 x2007
<chr> <chr> <dbl> <dbl> <dbl>
1 Australia Oceania 18565243 19546792 20434176
2 Brazil Americas 168546719 179914212 190010647
3 China Asia 1230075000 1280400000 1318683096
4 Egypt Africa 66134291 73312559 80264543
5 Germany Europe 82011073 82350671 82400996
6 India Asia 959000000 1034172547 1110396331
7 New Zealand Oceania 3676187 3908037 4115771
8 Nigeria Africa 106207839 119901274 135031164
9 Turkey Europe 63047647 67308928 71158647
10 United States Americas 272911760 287675526 301139947
We will use the gt function to create a table.
gt(): Create a gt table object (this is similar to creating a baseline plot object with ggplot()) and the function takes a massive number of arguments, some we will introduce here are the following:
We will explain what these mean in detail as we proceed through the chapter.
# Basic table# Creating a gt tablepopulation_for_select_countries_3y |>gt()
country
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
Once we have the gt table object, we style and edit it as we please.
Please note that her I am using grouped tibble (via dplyr’s group_by()) for more precise divisions of rows into row groups.
We can also use the arguments, rowname_col and groupname_col to do our groupings.
# Specifying the rowname and groupnamepopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent")
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
Typically, the data in the groupname_col will consist of categories of data in a table and the data in the rowname_col are unique labels (perhaps unique across the entire table or unique within groups).
Another useful function is the gt_preview() which shows a nicely-formatted preview of a data table (defaulting to the first 5 rows and the last row).
3.3 Titles and Subtitles
To add a heading and subtitle we can use the tab_header().
This includes a title and subtitle.
tab_header(): Add a table header and takes the following arguments:
data,
title,
subtitle = NULL
# Add Title and Subtitle# We use tab_header and specify the title and subtitle argumentspopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |>tab_header(title ="Table 1: Population of select countries over three years: Population of select countries over three years",subtitle ="This is my subtitle")
Table 1: Population of select countries over three years: Population of select countries over three years
This is my subtitle
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
We may also style the title and subtitle using Markdown or HTML formatting. We do this by wrapping the values passed to title or subtitle with the with md() or html().
# Add Title and Subtitle with markdownpopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |># Markdown formatingtab_header(title = gt::md("**Table 1: Population of select countries over three years: Population of select countries over three years**"),subtitle = gt::md("*Population for 1997, 2002 and 2007*") )
Table 1: Population of select countries over three years: Population of select countries over three years
Population for 1997, 2002 and 2007
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
3.4 Spanner and Stub head
A stub is a special column that contains row labels/names.
Just as with the stub, we can create groupings of columns with spanner column labels that encompass one or more columns. The tab_spanner() function makes this possible. This label is placed above one or more column labels, spanning the width of those columns and column labels.
Should the columns not be adjacent to each other, tab_spanner() will automatically gather them together.
tab_spanner(): Add a spanner column label and takes the following arguments:
data,
label,
columns,
gather = TRUE
tab_stubhead(): Add label text to the stubhead and takes some similar arguments:
data,
label
With the columns argument we can use column names in double quotes (“”), in vars() (vars()), or, we can use the following tidyselect expressions:
contains(): contains a literal string
matches(): matches a regular expression
starts_with(): starts with a prefix
ends_with(): ends with a suffix
everything(): selects all columns
These are covered in Introduction to R Chapter 4, so feel free to review these should you need a reminder.
# Add spanner and stub headpopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |>tab_header(title = gt::md("**Table 1: Population of select countries over three years**"),subtitle = gt::md("*Population for 1997, 2002 and 2007*") ) |># Add a spannertab_spanner(label = gt::md("**Years**"), columns =everything() ) |># Add a stub headtab_stubhead(label = gt::md("**Continent**") )
Table 1: Population of select countries over three years
Population for 1997, 2002 and 2007
Continent
Years
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
3.5 Source and Footnotes
A source note is useful for citing the data included in the table.
To add a source and footnote we can use the tab_source_note() and tab_footnote().
tab_source_note(): Add a source note citation, taking the following arguments:
data
source_note
# Source and footnotepopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |>tab_header(title = gt::md("**Table 1: Population of select countries over three years**"),subtitle = gt::md("*Population for 1997, 2002 and 2007*") ) |>tab_spanner(label = gt::md("**Years**"), columns =everything() ) |># Add a source notetab_source_note(source_note ="Gapminder.org")
Table 1: Population of select countries over three years
Population for 1997, 2002 and 2007
Years
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
Gapminder.org
Several can be added to the footer, simply use multiple calls of tab_source_note() and they will be inserted in the order provided.
Just like the headers we can also use Markdown formatting for the note
# Source and footnote - multiple (using markdown)population_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |>tab_header(title = gt::md("**Table 1: Population of select countries over three years**"),subtitle = gt::md("*Population for 1997, 2002 and 2007*") ) |>tab_spanner(label = gt::md("**Years**"), columns =everything() ) |># Add a source notetab_source_note(source_note = gt::md("Gapminder.org") ) |># Add another source notetab_source_note(source_note = gt::md("This is my second source note") )
Table 1: Population of select countries over three years
Population for 1997, 2002 and 2007
Years
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
Gapminder.org
This is my second source note
The formatting of the source notes can be controlled through the use of various parameters in the tab_options() function. We will look at this later on through the course.
tab_footnote(): Add a table footnote, using the following arguments:
data
footnote
locations
There are two components to a footnote:
A footnote mark that is attached to the targeted cell text, and
The footnote text (that starts with the corresponding footnote mark) that is placed in the table’s footer area.
The arguments we need to provide are footnote and locations.
Locations is the cell or set of cells to be associated with the footnote. Supplying any of the cells_*() helper functions is a useful way to target the location cells that are associated with the footnote text.
These helper functions are:
cells_title() - Location helper for targeting the table title and subtitle
cells_stubhead() - Location helper for targeting the table stubhead cell
cells_column_spanners() - Location helper for targeting the column spanners
cells_column_labels() - Location helper for targeting the column labels
cells_row_groups() - Location helper for targeting row groups
cells_stub() - Location helper for targeting cells in the table stub
cells_body() - Location helper for targeting data cells in the table body
cells_summary() - Location helper for targeting group summary cells
Additionally, we can enclose several cells_*() calls within a list() if we wish to link the footnote text to different types of locations (e.g., body cells, row group labels, the table title, etc.).
# We can footnotes using tab footnote - using locationspopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |>tab_header(title = gt::md("**Table 1: Population of select countries over three years**"),subtitle = gt::md("*Population for 1997, 2002 and 2007*") ) |>tab_source_note(source_note = gt::md("Gapminder.org") ) |>tab_spanner(label = gt::md("**Years**"), columns =everything() ) |>tab_source_note(source_note = gt::md("This is my second source note") ) |># Add a footnotetab_footnote(footnote ="This is my footnote",locations =cells_column_labels(columns = ("x1997")))
Table 1: Population of select countries over three
years
Population for 1997, 2002 and 2007
Years
x19971
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
Gapminder.org
This is my second source note
1 This is my footnote
We can add multiple footnotes.
# Multiple footnotespopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |>tab_header(title = gt::md("**Table 1: Population of select countries over three years**"),subtitle = gt::md("*Population for 1997, 2002 and 2007*") ) |>tab_spanner(label = gt::md("**Years**"), columns =everything() ) |>tab_source_note(source_note = gt::md("Gapminder.org") ) |>tab_source_note(source_note = gt::md("This is my second source note") ) |># Add a footnotetab_footnote(footnote ="This is my footnote",locations =cells_column_labels(columns = ("x1997") ) ) |># Add another footnotetab_footnote(footnote ="This is my second footnote",locations =cells_row_groups(groups =TRUE) )
Table 1: Population of select countries over three
years
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.
we can also allow gt to automatically choose the alignment of each column based on the data type (with the “auto” option).
3.7.2 Relabel Columns
We can relabel our columns using
cols_label(): Relabel one or more columns, with the following arguments:
data
… (old_name = “new_name”)
.list = list2(…)
Column labels can be modified from their default values (the names of the columns from the input table data).
When you create a gt table object using gt(), column names effectively become the column labels. While this serves as a good first approximation, column names aren’t often appealing as column labels in a gt output table. The cols_label() function provides the flexibility to relabel one or more columns.
cols_width(): Set the widths of columns with the following arguments:
data
…
.list = list2(…)
Manual specifications of column widths can be performed using the cols_width() function.
We choose which columns get specific widths (in pixels, usually by use of the px() helper function). Width assignments are supplied in “…” through two-sided formulas, where the left-hand side defines the target columns and the right-hand side is a single width value in pixels. This is similar to the case_when() function.
The … is covered in the Introduction to R - Control Flow and Functions section 5.7
The structure is very similar to the case when function which is covered in the the Introduction to R - Control Flow and Functions section 4.4.
3.7.4 Moving Columns
We can move columns using
cols_move(): Move one or more columns with the following arguments:
data
columns
after
On those occasions where you need to move columns this way or that way, we can make use of the cols_move() function. While it’s true that the movement of columns can be done upstream of gt’s API, it is much easier and less error prone to use the function provided here.
The movement procedure here takes one or more specified columns (in the columns argument) and places them to the right of a different column (the after argument). The ordering of the columns to be moved is preserved, as is the ordering of all other columns in the table.
cols_hide(): Hide one or more columns with the following arguments:
data
columns
The cols_hide() function allows us to hide one or more columns from appearing in the final output table. While it’s possible and often desirable to omit columns from the input table data before introduction to the gt() function, there can be cases where the data in certain columns is useful (as a column reference during formatting of other columns) but the final display of those columns is not necessary.
We can modify entire rows is the row_group_order():
row_group_order(): modify the display order of any row groups with the following arguments
data
groups
# modify the ordering of any row groupspopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |>row_group_order(groups =c("Africa","Asia","Americas","Europe","Oceania") )
x1997
x2002
x2007
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
3.8.2 Adding Summary Rows
There are two functions that will add rows to a gt table: summary_rows() and grand_summary_rows(). These are useful for adding groupwise and grand summary rows.
summary_rows() - Add groupwise summary rows using aggregation functions
grand_summary_rows() - Add grand summary rows using aggregation functions
summary_rows(): Add groupwise summary rows using aggregation functions with the following arguments:
data,
groups = NULL,
columns = TRUE,
fns,
missing_text = “—”,
formatter = fmt_number, …
# Add summary rowspopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |>summary_rows(groups =TRUE, # = `TRUE` works to target all groupscolumns =everything(),fns =list(my_total ="sum",my_mean ="mean") )
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
# Add summary rowspopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent") |>summary_rows(groups =TRUE, # = `TRUE` works to target all groupscolumns =everything(),fns =list(my_total ="sum",my_mean ="mean"),formatter = fmt_number,decimals =0)
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
grand_summary_rows(): Add grand summary rows using aggregation functions with the following arguments:
data
columns = TRUE
fns
missing_text = “—”
fmt = ~ (., …) …
Add grand summary rows to the gt table by using applying aggregation functions to the table data. The summary rows incorporate all of the available data, regardless of whether some of the data are part of row groups.
With the opt_*() functions, we have an easy way to set commonly-used table options. For example, we can modify the set of marks to use with footnotes, turn on row striping, change the alignment of the table header, and much more.
Important functions:
opt_footnote_marks()
opt_row_striping()
opt_align_table_header()
opt_all_caps()
opt_table_lines()
opt_table_outline()
opt_table_font()
opt_css()
Helpers for specifying fonts: - default_fonts()
3.12.1 Modify Footnotes
We can modify the footnote marks using,
opt_footnote_marks(): Modify the set of footnote marks with the following parameters:
data
marks
Either a vector of marks can be provided (including Unicode characters), or, a specific keyword could be used to signify a preset sequence.
# Alter footnote markspopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent" ) |>tab_footnote(footnote ="This is my footnote",locations =cells_column_labels(columns = ("x1997")) ) |>opt_footnote_marks(marks ="standard")
x1997*
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
* This is my footnote
3.12.2 Row Striping
By default, a gt table does not have row striping enabled. However, this function allows us to easily enable or disable striped rows in the table body.
By default, a table header added to a gt table has center alignment for both the title and the subtitle elements. This function allows us to easily set the horizontal alignment of the title and subtitle to the left or right by using the “align” argument.
opt_align_table_header(): Option to align the table header with the following parameters:
data
align = c(“left”, “center”, “right”)
# Align table header leftpopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent" ) |>tab_header(title ="Table 1: Population of select countries over three Years",subtitle ="Population for 1997, 2002 and 2007" ) |>opt_align_table_header(align ="left")
Table 1: Population of select countries over three Years
Population for 1997, 2002 and 2007
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
3.12.4 Capitalise
Sometimes an all-capitalized look is suitable for a table.
With the opt_all_caps() function, we can transform characters in the column labels, the stub, and in all row groups in this way (and there’s control over which of these locations are transformed).
opt_all_caps(): Option to use all caps in select table locations with the following parameters:
The opt_table_lines() function sets table lines in one of three possible ways:
all possible table lines drawn (“all”)
no table lines at all (“none”)
resetting to the default line styles (“default”).
This is great if you want to start off with lots of lines and subtract just a few of them with tab_style(). Or, use it to start with a completely lineless table, adding individual lines as needed.
opt_table_outline(): Option to wrap an outline around the entire table with the following parameters:
data
style = “solid”
width = px(3)
color = “#D3D3D3”
This function puts an outline of consistent style, width, and color around the entire table. It’ll write over any existing outside lines so long as the width is larger that of the existing lines.
The default value of style (“solid”) will draw a solid outline, whereas a value of “none” will remove any present outline.
The opt_table_font() function makes it possible to define a custom font for the entire gt table. The standard fallback fonts are still set by default but the font defined here will take precedence. You could still have different fonts in select locations in the table, and for that you would need to use tab_style() in conjunction with the cell_text() helper function.
opt_table_font(): Option to define a custom font for the table with the following parameters:
data
font
weight = NULL
style = NULL
add = TRUE
# Amend fonts for entire tablepopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent" ) |>opt_table_font(font ="Times New Roman")
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
3.13 Tab Options
This section contains a ton of options we can amend. We can either use the common options with the opt_*() functions or we can use the tab_options.
tab_options(): Modify the table output options which can take over 100 parameters, check the documentation to see the numerous applications available to us.
3.13.1 Borders
# Style and borderspopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent" ) |>tab_options( # change the column labels sectioncolumn_labels.border.bottom.color ="black",column_labels.border.top.color ="black",column_labels.border.bottom.width =3,column_labels.border.top.width =3,# change the bottom of the bodytable_body.border.bottom.color ="black" )
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
3.13.2 Table Width
Modify the table width (with table.width) to 100% (which spans the entire content width area).
# Make the width 100% using the pct() helper functionpopulation_for_select_countries_3y |>gt(rowname_col ="country",groupname_col ="continent" ) |>tab_options( # make the width 100%table.width =pct(100) )
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
3.13.3 Background Colour
Modify the table’s background color (with table.background.color).
Similar to ggplot themes we can create a function with our table layout and styles. We can use this function on multiple tables that we wish to have the same styles.
For a reminder on writing User Defined Functions (UDFs), refer to Control Flow, Loops and Functions in R.
# Creating a function to theme different tables, reducing code repetitiontable_style_function <-function(table_data) {gt(table_data) |>tab_options( # change the column labels sectioncolumn_labels.border.bottom.color ="black",column_labels.border.top.color ="black",column_labels.border.bottom.width =3,column_labels.border.top.width =3,table.width =pct(100),table.background.color ="white",# change the bottom of the bodytable_body.border.bottom.color ="black",heading.title.font.size =px(16), ) |>cols_align(align ="center") |>opt_align_table_header(align ="left") |>tab_style(style =cell_borders(sides =c("top", "bottom"),color ="white",weight =px(1) ),locations =cells_body(columns =everything(),rows =everything() ) )}
We can use apply our function either specifying the table data argument or using within a pipe.
# We can apply our function as an argumentpopulation_for_select_countries_3y |>table_style_function()
country
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
We can then add additional formatting similar to way we did with ggplot.
# We can add additional formatingpopulation_for_select_countries_3y |>table_style_function() |>tab_header(title = gt::md("**Table 1: Population of select countries over three years**"),subtitle = gt::md("*Population for 1997, 2002 and 2007*") )
Table 1: Population of select countries over three years
Population for 1997, 2002 and 2007
country
x1997
x2002
x2007
Oceania
Australia
18565243
19546792
20434176
New Zealand
3676187
3908037
4115771
Americas
Brazil
168546719
179914212
190010647
United States
272911760
287675526
301139947
Asia
China
1230075000
1280400000
1318683096
India
959000000
1034172547
1110396331
Africa
Egypt
66134291
73312559
80264543
Nigeria
106207839
119901274
135031164
Europe
Germany
82011073
82350671
82400996
Turkey
63047647
67308928
71158647
3.15 Saving Tables
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.
gtsave(): Save a gt table as a file with the following parameters:
data
filename
path = NULL
…
trick is to name the file in a supported format (e.g., “gt_table.rtf” for an RTF file containing the table).
# Change the column labels section# Change the bottom of the bold# Align columns# Tab style to fill in grey# Tab style to highlight to redexibble |>gt(rowname_col ="row",groupname_col ="group" ) |>tab_options() |># Change borderscols_align() |># Align columnstab_style() |># Tab style to fill in greytab_style() |># Tab style to highlight to redtab_style()
# Change the column labels section# Change the bottom of the bod# Align columns# Tab style to fill in grey# Tab style to highlight to redexibble |>gt(rowname_col ="row",groupname_col ="group" ) |>tab_options( # change the column labels sectioncolumn_labels.border.bottom.color ="black",column_labels.border.top.color ="black",column_labels.border.bottom.width =3,column_labels.border.top.width =3,table.width =pct(100),table.background.color ="white",# change the bottom of the bodytable_body.border.bottom.color ="black" ) |>cols_align(align ="center") |>tab_style(style =cell_borders(sides =c("top", "bottom"),color ="white" ),locations =cells_body(columns =everything(),rows =everything() ) ) |>tab_style(style =list(cell_fill(color ="lightgrey"),cell_borders(side =c("left", "right"),color ="black",weight =px(2) ) ),locations =cells_body(columns =c(currency) ) ) |>tab_style(cell_text(color ="red"),locations =cells_body(columns =c(char),rows = char =="coconut" ) )
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
3.17 Best Practice
For full guidance refer to the Tables section of the Analysis Function guidance hub.
The font type and size should match the font used in your publication. The font should be mono-spaced, with the same width for each character or digit, so that all the units align. Serifed fonts are usually harder to read for dyslexic readers, so we recommend that you use an accessible, sans serif font like Arial, Helvetica, Myriad Pro, Lucida Sans, Open Sans or Verdana.
Do not put numbers in bold as they will move from their correct alignment. Present the numbers close together in columns, not rows and we should always separate out thousands with commas to make them easier to read.
Always right-align headings and data in columns so that units, tens, hundreds and thousands are aligned and numbers of equal value are easily comparable.
Use the same measure across all variables where possible.
Use lines and shading sparingly. Use subtle colours or greyscale. Make sure the shading does not distract from the data. Shading can be used to track data across rows but also to highlight specific values.
All tables should have a title to make the purpose of the table clear, as well as a sub-heading which is more statistical/technical in nature.
Make your column titles clear. Try using boldface type or lines to offset them from the numbers and text in the body of the table. The headings should also state the units of the row/column unless the entire table adheres to the same unit.
Right-align numbers along the decimal place or comma. We might need to add zeros to maintain the alignment, but it’s worth it so the numbers are easier to read and scan.
Example Table
Image taken from: (https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/deaths/bulletins/deathsinvolvingcovid19englandandwales/deathsoccurringinjune2020) Section 7.
We can recreate the table in the image above, data can be downloaded in the link above.
# Creating our tablecovid_table_data |>gt() |># headertab_header(title =md("Median registration delay, lower and upper quartiles, minimum and maximum delay for deaths occurring in England and Wales, March to June 2020")) |># Adding Source Notes <br> for the spacestab_source_note(source_note =md("Source: Office for National Statistics – Deaths involving COVID-19 <br> <br>")) |>tab_source_note(source_note =md("Notes <br> <br>")) |>tab_source_note(source_note ="1. Figures are provisional.") |>tab_source_note(source_note ="2. Based on deaths occurring in March to June 2020 rather than deaths registered in March to June 2020.") |>tab_source_note(source_note ="3. Including deaths registered up until 4 July 2020.") |># Bold column labelstab_style(style =cell_text(weight ="bold"),locations =cells_column_labels(everything()) ) |># Table linesopt_table_lines(extent ="default") |># Align Headeropt_align_table_header("left") |>cols_label(statistics_days ="Statistics(days)",all_causes_of_death ="All causes of death",deaths_involving_covid_19 ="Deaths involving COVID-19" ) |># Column border labelstab_options(table.border.top.color ="white",table.border.bottom.color ="white",column_labels.border.top.width =px(3),column_labels.border.bottom.width =px(3),row_group.border.right.color ="white",row_group.border.left.width ="white" )
Median registration delay, lower and upper quartiles, minimum and maximum delay for deaths occurring in England and Wales, March to June 2020
Statistics(days)
All causes of death
Deaths involving COVID-19
Median registration delay
4
4
Lower quartile
2
2
Upper quartile
6
6
Minimum
0
0
Maximum
123
113
Source: Office for National Statistics – Deaths involving COVID-19
Notes
1. Figures are provisional.
2. Based on deaths occurring in March to June 2020 rather than deaths registered in March to June 2020.
3. Including deaths registered up until 4 July 2020.
Terrific work creating those tables! This was a long and complex chapter since there is so much formatting that can be done to tables at multiple levels (be they the table itself, at the cell level, header level and so on) so you deserve a much needed break after covering that!
That actually brings us to the end of the Reference Material, proceed to the Summary Chapter 7 for additional links/references as well as information on what the next best steps are.