Tables often need to convey more than what fits neatly in rows and columns. A value might require clarification. A column heading might benefit from a definition. The data source might need acknowledgment. Footnotes and source notes address these needs, providing a structured way to add supplementary information without cluttering the main table body.
In gt, the footer section accommodates two types of annotations: footnotes (linked to specific table locations via marks) and source notes (general citations or commentary). This chapter explores how to add both, how to target specific table locations for footnote attachment, and how to customize the appearance of footnote marks and the footer layout.
9.1 The footer section
The footer sits beneath the table body and serves as the home for supplementary text. It’s divided conceptually into two areas: footnotes appear first, followed by source notes. Both are optional as a table might have neither, one, or both.
Footnotes connect to specific content through marks (typically numbers, letters, or symbols). A reader sees the mark in the table, then finds the corresponding explanation in the footer. Source notes, by contrast, stand alone without marks; they provide general context such as data provenance.
9.2 Adding footnotes
9.2.1tab_footnote() and the cells_*() location helpers
The tab_footnote() function can make it a painless process to add a footnote to a gt table. There are commonly two components to a footnote: (1) a footnote mark that is attached to the targeted cell content, and (2) the footnote text itself that is placed in the table’s footer area. Each unit of footnote text in the footer is linked to an element of text or otherwise through the footnote mark. The footnote system in gt presents footnotes in a way that matches the usual expectations, where:
footnote marks have a sequence, whether they are symbols, numbers, or letters
multiple footnotes can be applied to the same content (and marks are always presented in an ordered fashion)
footnote text in the footer is never exactly repeated, gt reuses footnote marks where needed throughout the table
footnote marks are ordered across the table in a consistent manner (left to right, top to bottom)
The text to be used in the footnote. We can optionally use the md() and html() functions to style the text as Markdown or to retain HTML elements in the footnote text.
locations: Locations to target
<locations expressions> // default: NULL, so optional
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. 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.).
placement: Placement of footnote mark
singl-kw:[auto|right|left] // default: "auto"
Where to affix footnote marks to the table content. Two options for this are "left" or "right", where the placement is either to the absolute left or right of the cell content. By default, however, this option is set to "auto" whereby gt will choose a preferred left-or-right placement depending on the alignment of the cell content.
Using a subset of the sza dataset, let’s create a new gt table. The sza column will get all of its cells filled with a background color according to data values (this is done with data_color()) and then the use of tab_footnote() lets us add a footnote to the sza column label (explaining what the color gradient signifies).
Of course, we can add more than one footnote to the table, but, we have to use several calls of tab_footnote(). This variation of the sza table has three footnotes: one on the "TST" column label and two on the "SZA" column label (these were capitalized with opt_all_caps()). We have three calls of tab_footnote() and while the order of calls usually doesn’t matter, it does have a subtle effect here since two footnotes are associated with the same text content (try reversing the second and third calls and observe the effect in the footer).
sza|>dplyr::filter(latitude==20&month=="jan"&!is.na(sza))|>dplyr::select(-latitude, -month)|>gt()|>opt_all_caps()|>cols_align(align ="center")|>cols_width(everything()~px(200))|>tab_footnote( footnote =md("TST stands for *True Solar Time*."), locations =cells_column_labels(columns =tst))|>tab_footnote( footnote =md("SZA stands for *Solar Zenith Angle*."), locations =cells_column_labels(columns =sza))|>tab_footnote( footnote ="Higher Values indicate sun closer to horizon.", locations =cells_column_labels(columns =sza))|>tab_options(footnotes.multiline =FALSE)
tst1
sza2,3
0700
84.9
0730
78.7
0800
72.7
0830
66.1
0900
61.5
0930
56.5
1000
52.1
1030
48.3
1100
45.5
1130
43.6
1200
43.0
1TST stands for True Solar Time.2SZA stands for Solar Zenith Angle.3 Higher Values indicate sun closer to horizon.
Text in the footer (both from footnotes and also from source notes) tends to widen the table and all the columns within in. We can limit that setting column widths, which is what was done above with cols_width(). There can also be a correspondingly large amount of vertical space taken up by the footer since footnotes will, by default, each start on a new line. In the above example, we used tab_options(footnotes.multiline = FALSE) to make it so that all footer text is contained in a single block of text.
Let’s move on to another footnote-laden table, this one based on the towny dataset. We have a header part, with a title and a subtitle. We can choose which of these could be associated with a footnote and in this case it is the "subtitle" (one of two options in the cells_title() helper function). This table has a stub with row labels and some of those labels are associated with a footnote. So long as row labels are unique, they can be easily used as row identifiers in cells_stub(). The third footnote is placed on the "Density" column label. Here, changing the order of the tab_footnote() calls has no effect on the final table rendering.
towny|>dplyr::filter(csd_type=="city")|>dplyr::arrange(desc(population_2021))|>dplyr::select(name, density_2021, population_2021)|>dplyr::slice_head(n =10)|>gt(rowname_col ="name")|>tab_header( title =md("The 10 Largest Municipalities in `towny`"), subtitle ="Population values taken from the 2021 census.")|>fmt_integer()|>cols_label( density_2021 ="Density", population_2021 ="Population")|>tab_footnote( footnote ="Part of the Greater Toronto Area.", locations =cells_stub(rows =c("Toronto", "Mississauga", "Brampton", "Markham", "Vaughan")))|>tab_footnote( footnote =md("Density is in terms of persons per km^2^."), locations =cells_column_labels(columns =density_2021))|>tab_footnote( footnote ="Census results made public on February 9, 2022.", locations =cells_title(groups ="subtitle"))|>tab_source_note(source_note =md("Data taken from the `towny` dataset (in the **gt** package)."))|>opt_footnote_marks(marks ="letters")
The 10 Largest Municipalities in towny
Population values taken from the 2021 census.a
Densityb
Population
Torontoc
4,428
2,794,356
Ottawa
365
1,017,449
Mississaugac
2,453
717,961
Bramptonc
2,469
656,480
Hamilton
509
569,353
London
1,004
422,324
Markhamc
1,605
338,503
Vaughanc
1,186
323,103
Kitchener
1,878
256,885
Windsor
1,573
229,660
a Census results made public on February 9, 2022.
bDensity is in terms of persons per km2.
c Part of the Greater Toronto Area.
Data taken from the towny dataset (in the gt package).
In the above table, we elected to change the footnote marks to letters instead of the default numbers (done through opt_footnote_marks()). A source note was also added; this was mainly to demonstrate that source notes will be positioned beneath footnotes in the footer section.
For our final example, let’s make a relatively small table deriving from the sp500 dataset. The set of tab_footnote() calls used here (four of them) have minor variations that allow for interesting expressions of footnotes. Two of the footnotes target values in the body of the table (using the cells_body() helper function to achieve this). On numeric values that right-aligned, gt will opt to place the footnote on the left of the content so as to not disrupt the alignment. However, the placement argument can be used to force the positioning of the footnote mark after the content.
We can also opt to include footnotes that have no associated footnote marks whatsoever. This is done by not providing anything to locations. These ‘markless’ footnotes will precede the other footnotes in the footer section.
sp500|>dplyr::filter(date>="2015-01-05"&date<="2015-01-10")|>dplyr::select(-c(adj_close, volume, high, low))|>dplyr::mutate(change =close-open)|>dplyr::arrange(date)|>gt()|>tab_header(title ="S&P 500")|>fmt_date(date_style ="m_day_year")|>fmt_currency()|>cols_width(everything()~px(150))|>tab_footnote( footnote ="More red days than green in this period.", locations =cells_column_labels(columns =change))|>tab_footnote( footnote ="Lowest opening value.", locations =cells_body(columns =open, rows =3),)|>tab_footnote( footnote ="Devastating losses on this day.", locations =cells_body(columns =change, rows =1), placement ="right")|>tab_footnote(footnote ="All values in USD.")|>opt_footnote_marks(marks ="LETTERS")|>opt_footnote_spec(spec_ref ="i[x]", spec_ftr ="x.")
S&P 500
date
open
close
change[A]
Jan 5, 2015
$2,054.44
$2,020.58
−$33.86[B]
Jan 6, 2015
$2,022.15
$2,002.61
−$19.54
Jan 7, 2015
[C] $2,005.55
$2,025.90
$20.35
Jan 8, 2015
$2,030.61
$2,062.14
$31.53
Jan 9, 2015
$2,063.45
$2,044.81
−$18.64
All values in USD.
A. More red days than green in this period.
B. Devastating losses on this day.
C. Lowest opening value.
Aside from changing the footnote marks to be "LETTERS", we’ve also changed the way the marks are formatted. In opt_footnote_spec() the spec_ref option, governing the footnote marks across the table, describes marks that are italicized and set between square brackets ("i[x]"). The spec_ftr argument is for the footer representation of the footnote marks and as described in the call with "x.", it’ll be the mark followed by a period.
9.3 Location helpers for footnotes
The power of tab_footnote() lies in its ability to target virtually any part of the table. The locations argument accepts various cells_*() helper functions, each designed to select specific table regions.
9.3.1 Targeting column labels with cells_column_labels()
Column labels are common footnote targets and they often benefit from definitions or clarifications:
gtcars|>dplyr::select(mfr, model, hp, mpg_c, mpg_h)|>dplyr::slice_head(n =5)|>gt()|>cols_label( mfr ="Manufacturer", model ="Model", hp ="Horsepower", mpg_c ="City MPG", mpg_h ="Highway MPG")|>tab_footnote( footnote ="Miles per gallon in city driving conditions.", locations =cells_column_labels(columns =mpg_c))|>tab_footnote( footnote ="Miles per gallon on highway.", locations =cells_column_labels(columns =mpg_h))
Manufacturer
Model
Horsepower
City MPG1
Highway MPG2
Ford
GT
647
11
18
Ferrari
458 Speciale
597
13
17
Ferrari
458 Spider
562
13
17
Ferrari
458 Italia
562
13
17
Ferrari
488 GTB
661
15
22
1 Miles per gallon in city driving conditions.
2 Miles per gallon on highway.
Each column label receives its own footnote mark, and the footer displays both explanations. The columns argument in cells_column_labels() accepts column names, indices, or tidyselect helpers.
9.3.2 Targeting multiple columns at once
When several columns share a common characteristic, you can attach one footnote to all of them:
Both “City” and “Highway” column labels receive the same footnote mark, and only one entry appears in the footer. This demonstrates gt’s intelligent handling of duplicate footnotes.
9.3.3 Targeting body cells with cells_body()
Footnotes can attach to specific data values when individual cells need explanation:
exibble|>dplyr::select(row, num, currency)|>gt(rowname_col ="row")|>fmt_number(columns =num, decimals =2)|>fmt_currency(columns =currency)|>tab_footnote( footnote ="Highest value in dataset.", locations =cells_body(columns =num, rows =num==max(num, na.rm =TRUE)))|>tab_footnote( footnote ="Missing data point.", locations =cells_body(columns =num, rows =is.na(num)))
num
currency
row_1
0.11
$49.95
row_2
2.22
$17.95
row_3
33.33
$1.39
row_4
444.40
$65,100.00
row_5
5,550.00
$1,325.81
row_6
1 NA
$13.26
row_7
777,000.00
NA
row_8
2 8,880,000.00
$0.44
1 Missing data point.
2 Highest value in dataset.
The rows argument accepts logical conditions, row numbers, or row names. Here, we identify cells programmatically: one by value comparison, another by detecting missingness.
9.3.4 Targeting stub cells with cells_stub()
When rows have labels (a stub column), those labels can receive footnotes:
pizzaplace|>dplyr::count(type, name ="orders")|>dplyr::arrange(desc(orders))|>gt(rowname_col ="type")|>fmt_integer(columns =orders)|>tab_header(title ="Pizza Orders by Type")|>tab_footnote( footnote ="Traditional Italian-American style.", locations =cells_stub(rows ="classic"))|>tab_footnote( footnote ="Specialty recipes with premium toppings.", locations =cells_stub(rows ="supreme"))
Pizza Orders by Type
orders
classic1
14,888
supreme2
11,987
veggie
11,649
chicken
11,050
1 Traditional Italian-American style.
2 Specialty recipes with premium toppings.
Row labels in the stub serve as identifiers, so you can reference them directly by name.
9.3.5 Targeting row group labels with cells_row_groups()
When tables have grouped rows, the group labels can also receive footnotes:
gtcars|>dplyr::select(mfr, model, year, hp)|>dplyr::filter(mfr%in%c("Ferrari", "Lamborghini", "Maserati"))|>gt(rowname_col ="model", groupname_col ="mfr")|>tab_footnote( footnote ="Part of the Fiat Chrysler Automobiles group.", locations =cells_row_groups(groups =c("Ferrari", "Maserati")))
year
hp
Ferrari1
458 Speciale
2015
597
458 Spider
2015
562
458 Italia
2014
562
488 GTB
2016
661
California
2015
553
GTC4Lusso
2017
680
FF
2015
652
F12Berlinetta
2015
731
LaFerrari
2015
949
Lamborghini
Aventador
2015
700
Huracan
2015
610
Gallardo
2014
550
Maserati1
Granturismo
2016
454
Quattroporte
2016
404
Ghibli
2016
345
1 Part of the Fiat Chrysler Automobiles group.
Multiple row groups can share the same footnote when they have something in common.
9.3.6 Targeting titles with cells_title()
The header section, containing a title and a subtitle, can also host footnotes:
countrypops|>dplyr::filter(country_name%in%c("United States", "China", "India"),year==2022)|>dplyr::select(country_name, population)|>gt(rowname_col ="country_name")|>fmt_number(columns =population, suffixing =TRUE)|>tab_header( title ="World's Most Populous Countries", subtitle ="Population estimates for 2022")|>tab_footnote( footnote ="Based on UN World Population Prospects.", locations =cells_title(groups ="subtitle"))
World's Most Populous Countries
Population estimates for 20221
population
China
1.41B
India
1.43B
United States
334.02M
1 Based on UN World Population Prospects.
The groups argument specifies whether to target "title" or "subtitle".
9.3.7 Targeting column spanners with cells_column_spanners()
Column spanners, labels that span multiple columns, can receive footnotes too:
The spanners argument takes the spanner label text.
9.3.8 Targeting the stubhead with cells_stubhead()
If your table has both a stub and a stubhead label, that label can receive footnotes:
towny|>dplyr::select(name, population_2021, density_2021)|>dplyr::slice_max(population_2021, n =5)|>gt(rowname_col ="name")|>tab_stubhead(label ="Municipality")|>fmt_integer()|>cols_label( population_2021 ="Population", density_2021 ="Density")|>tab_footnote( footnote ="Census subdivisions classified as cities or towns.", locations =cells_stubhead())
Municipality1
Population
Density
Toronto
2,794,356
4,428
Ottawa
1,017,449
365
Mississauga
717,961
2,453
Brampton
656,480
2,469
Hamilton
569,353
509
1 Census subdivisions classified as cities or towns.
The cells_stubhead() helper takes no arguments as there’s only one stubhead per table.
9.3.9 Targeting summary rows
Summary rows (created with summary_rows() or grand_summary_rows()) can receive footnotes using cells_summary(), cells_grand_summary(), cells_stub_summary(), or cells_stub_grand_summary():
Both column labels receive the same footnote mark, consolidating related information.
9.4 Unmarked footnotes
Sometimes you want footer text without a corresponding mark in the table. Omitting the locations argument creates an unmarked footnote:
gtcars|>dplyr::select(mfr, model, year, msrp)|>dplyr::slice_head(n =5)|>gt()|>fmt_currency(columns =msrp, decimals =0)|>cols_label( mfr ="Make", model ="Model", year ="Year", msrp ="MSRP")|>tab_footnote(footnote ="All prices in US dollars.")|>tab_footnote(footnote ="Data current as of 2016.")
Make
Model
Year
MSRP
Ford
GT
2017
$447,000
Ferrari
458 Speciale
2015
$291,744
Ferrari
458 Spider
2015
$263,553
Ferrari
458 Italia
2014
$233,509
Ferrari
488 GTB
2016
$245,400
All prices in US dollars.
Data current as of 2016.
Unmarked footnotes appear in the footer without any superscript reference. They’re useful for general notes that apply to the entire table.
9.5 Footnote mark placement
The placement argument controls where the footnote mark appears relative to cell content:
By default (placement = "auto"), gt places marks on the left for right-aligned content (to preserve numeric alignment) and on the right for left-aligned content. You can override this with explicit "left" or "right" values.
9.6 Source notes with tab_source_note()
Source notes provide citations or general commentary without linking to specific table locations. They appear beneath any footnotes in the footer.
Function Signature
tab_source_note(data,source_note)
gtcars|>dplyr::select(mfr, model, year, hp, msrp)|>dplyr::slice_head(n =5)|>gt()|>fmt_currency(columns =msrp, decimals =0)|>cols_label( mfr ="Make", model ="Model", year ="Year", hp ="HP", msrp ="Price")|>tab_source_note( source_note ="Data from edmunds.com, collected in 2016.")
Make
Model
Year
HP
Price
Ford
GT
2017
647
$447,000
Ferrari
458 Speciale
2015
597
$291,744
Ferrari
458 Spider
2015
562
$263,553
Ferrari
458 Italia
2014
562
$233,509
Ferrari
488 GTB
2016
661
$245,400
Data from edmunds.com, collected in 2016.
Source notes support markdown and HTML formatting:
countrypops|>dplyr::filter(country_name=="United States", year>=2018)|>dplyr::select(year, population)|>gt()|>fmt_number(columns =population, suffixing =TRUE)|>tab_header(title ="US Population Growth")|>tab_source_note( source_note =md("Source: *UN World Population Prospects* (2022 revision)"))|>tab_source_note( source_note =md("Available at [population.un.org](https://population.un.org)"))
US Population Growth
year
population
2018
328.53M
2019
330.23M
2020
331.58M
2021
332.10M
2022
334.02M
2023
336.81M
2024
340.11M
Source: UN World Population Prospects (2022 revision)
The specification string lets you combine multiple formatting options. For example, you might want marks in the table to be superscript and bold for visibility, while marks in the footer use a different style to fit the surrounding text.
Here, marks in the table are superscript and bold (^b), while marks in the footer appear in parentheses ((x)).
9.8.2 Academic-style footnotes
Academic journals often have specific requirements for footnote formatting. A common convention uses superscript italic letters in the table body with a period following each mark in the footer.
Superscript italicized letters in the table, with a trailing period in the footer, a common academic convention.
9.8.3 Bracketed footnotes
Technical documentation and some scientific fields prefer bracketed numbers over superscripts. This style keeps marks at baseline level, which some readers find less disruptive to reading flow.
"preserve_order": Footnotes appear in the order tab_footnote() was called
gtcars|>dplyr::select(mfr, model, hp, mpg_c)|>dplyr::slice_head(n =5)|>gt()|>cols_label( mfr ="Make", model ="Model", hp ="HP", mpg_c ="MPG")|>tab_footnote(footnote ="All specifications from manufacturer.")|>tab_footnote( footnote ="Brake horsepower.", locations =cells_column_labels(columns =hp))|>tab_footnote(footnote ="EPA city driving estimate.")|>tab_footnote( footnote ="City fuel economy.", locations =cells_column_labels(columns =mpg_c))|>opt_footnote_order(order ="marks_first")
Make
Model
HP1
MPG2
Ford
GT
647
11
Ferrari
458 Speciale
597
13
Ferrari
458 Spider
562
13
Ferrari
458 Italia
562
13
Ferrari
488 GTB
661
15
1 Brake horsepower.
2 City fuel economy.
All specifications from manufacturer.
EPA city driving estimate.
With "marks_first", the two marked footnotes (for HP and MPG) appear before the two unmarked footnotes.
9.10 Styling the footer
The footer, comprising both footnotes and source notes, can be styled using tab_style() with the cells_footnotes() and cells_source_notes() location helpers.
9.10.1 Styling footnotes
Footnote text can be styled to visually distinguish it from the main table content. Common choices include smaller font sizes, muted colors, or subtle background fills that signal the supplementary nature of the information.
1 Color gradient indicates solar zenith angle magnitude.
The footnote text becomes smaller, gray, with a light background (visually distinguished from the main table).
9.10.2 Styling source notes
Source notes often benefit from even more subdued styling than footnotes, since they provide attribution rather than essential clarifications. Italic text at a smaller size is a common convention for citations.
1 Numeric values. 2 Text strings. 3 Currency amounts.
All footnotes flow together in a single block, separated by spaces.
9.11.2 Footer padding and borders
The spacing around footnotes and source notes, along with any dividing lines, can be adjusted to match your table’s overall design. Tighter padding creates a more compact appearance, while borders can separate the footer from the table body or distinguish footnotes from source notes.
Fine control over padding and borders helps integrate the footer with your overall table design.
9.12 Practical examples
The techniques covered in this chapter come together in real-world tables where footnotes serve multiple purposes simultaneously. The following examples demonstrate how to combine location targeting, mark customization, and footer styling to create polished, professional tables.
9.12.1 Comprehensive financial table
Financial reports often require extensive annotation: definitions for technical terms, clarifications for unusual values, and source citations for data provenance. This example shows how multiple footnote types work together in a single table.
sp500|>dplyr::filter(date>="2015-01-05"&date<="2015-01-09")|>dplyr::select(date, open, high, low, close, volume)|>dplyr::mutate( change =close-open, pct_change =(close-open)/open)|>gt()|>tab_header( title ="S&P 500 Daily Performance", subtitle ="First trading week of 2015")|>fmt_date(columns =date, date_style ="yMMMd")|>fmt_currency(columns =c(open, high, low, close, change))|>fmt_percent(columns =pct_change, decimals =2)|>fmt_number(columns =volume, suffixing =TRUE)|>cols_label( date ="Date", open ="Open", high ="High", low ="Low", close ="Close", volume ="Volume", change ="Change", pct_change ="% Change")|>tab_footnote( footnote ="New York Stock Exchange opening price.", locations =cells_column_labels(columns =open))|>tab_footnote( footnote ="Intraday trading range.", locations =cells_column_labels(columns =c(high, low)))|>tab_footnote( footnote ="Shares traded (approximate).", locations =cells_column_labels(columns =volume))|>tab_footnote( footnote ="Worst single-day performance of the week.", locations =cells_body(columns =pct_change, rows =pct_change==min(pct_change)))|>tab_footnote(footnote ="All values in USD.")|>tab_source_note( source_note =md("Data: *Yahoo Finance* via the **gt** package"))|>opt_footnote_marks(marks ="standard")|>opt_footnote_spec(spec_ref ="^", spec_ftr ="x —")|>tab_options(footnotes.multiline =FALSE)
S&P 500 Daily Performance
First trading week of 2015
Date
Open*
High†
Low†
Close
Volume‡
Change
% Change
Jan 9, 2015
$2,063.45
$2,064.43
$2,038.33
$2,044.81
3.36B
−$18.64
−0.90%
Jan 8, 2015
$2,030.61
$2,064.08
$2,030.61
$2,062.14
3.93B
$31.53
1.55%
Jan 7, 2015
$2,005.55
$2,029.61
$2,005.55
$2,025.90
3.81B
$20.35
1.01%
Jan 6, 2015
$2,022.15
$2,030.25
$1,992.44
$2,002.61
4.46B
−$19.54
−0.97%
Jan 5, 2015
$2,054.44
$2,054.44
$2,017.34
$2,020.58
3.80B
−$33.86
§ −1.65%
All values in USD. * New York Stock Exchange opening price. † Intraday trading range. ‡ Shares traded (approximate). § Worst single-day performance of the week.
Data: Yahoo Finance via the gt package
This financial table demonstrates multiple footnote targets, both marked and unmarked footnotes, customized marks, and styled footer elements.
9.12.2 Research table with citations
Scientific and clinical publications have their own footnote conventions, often favoring letters or symbols over numbers and requiring precise citation formatting. This example shows a clinical laboratory report with footnotes on column spanners, stub cells, and a properly formatted source citation.
Laboratory procedures per Clinical Chemistry standards (2023)
This clinical research table uses superscript italic marks, attaches footnotes to spanners and stub cells, and includes a properly cited source note.
Footnotes transform tables from bare data presentations into documented, contextualized reports. Whether explaining methodology, defining terms, citing sources, or highlighting anomalies, the footer section provides structured space for the supplementary information that readers need. With gt’s flexible location helpers and extensive customization options, you can craft footnotes that integrate seamlessly with any table design.
9.13 Summary
This chapter has covered the footer section of gt tables, where footnotes and source notes provide supplementary information without cluttering the main presentation.
The key concepts we’ve explored:
footnotes link explanatory text to specific table locations via marks. The tab_footnote() function attaches notes to cells, columns, rows, spanners, or any other table element using the cells_*() location helpers.
source notes provide general context (typically data citations) without marks. Multiple tab_source_note() calls add notes in sequence, and both md() and html() helpers enable rich formatting.
footnote marks can be customized with opt_footnote_marks() (choosing numbers, letters, standard symbols, or extended symbols) and opt_footnote_spec() (controlling superscript, parentheses, and other formatting).
location targeting uses the same cells_*() functions found throughout gt: cells_body(), cells_column_labels(), cells_stub(), cells_column_spanners(), cells_row_groups(), cells_summary(), and more.
mark placement can be controlled with the placement argument, positioning marks to the left or right of cell content.
Footnotes serve multiple purposes: defining abbreviations, explaining methodology, noting data limitations, citing sources, and highlighting exceptions. The key is using them well. Too many footnotes can overwhelm a table, while strategic footnotes enhance understanding.
The next chapter introduces nanoplots: tiny embedded visualizations that add a visual dimension to tabular data. You’ll learn to create line plots, bar plots, and box plots that fit within table cells, revealing trends and distributions at a glance.