gt-轻松制作表格

tidyverse
packages study
表格
Author

Lee

Published

June 18, 2026

pacman::p_load(
  tidyverse,
  gt,
  gtsummary, # gt扩展包,提供了数据摘要表格的功能
  gtExtras, # gt扩展包,提供了针对gt包的额外功能
  tablespan, # gt扩展包,可以将表格输出至excel
  gto, # gt扩展包,可以将表格输出至word和ppt
  janitor
)

gt包将表格分解为一套连贯的部件,通过这些部件创建表格。这些部件如图 图 1 所示。

图 1: gt表格的部件

通过gt创建的表格的典型步骤如图 图 2 所示

图 2: gt工作流

通过一个例子,使用gt包附带的sp500数据集简单演示一下gt的使用。

# define the start and end dates for data range
start_date <- "2010-06-07"
end_date <- "2020-06-14"

# 通过gt建立表格
# 以下是添加注释后的代码:

sp500 |> # 使用管道操作符(|>)将sp500数据集传递给后续操作
  dplyr::filter(date >= start_date & date <= end_date) |> # 筛选日期在start_date和end_date之间的数据
  dplyr::select(-adj_close) |> # 移除adj_close列(负号表示排除该列)
  slice_head(n = 10) |> # 只保留前10行数据
  gt() |> # 使用gt包创建美观的表格
  tab_header(
    title = "S&P 500", # 设置表格主标题为"S&P 500"
    subtitle = glue::glue("{start_date} to {end_date}") # 使用glue设置副标题为日期范围
  ) |>
  fmt_currency() |> # 将所有数值列格式化为货币格式
  fmt_date(columns = date, date_style = "wd_m_day_year") |> # 将date列格式化为"星期, 月 日, 年"的日期格式
  fmt_number(columns = volume, suffixing = TRUE) # 将volume列格式化为带有千(K)、百万(M)等后缀的数字格式
S&P 500
2010-06-07 to 2020-06-14
date open high low close volume
Thu, Dec 31, 2015 $2,060.59 $2,062.54 $2,043.62 $2,043.94 2.66B
Wed, Dec 30, 2015 $2,077.34 $2,077.34 $2,061.97 $2,063.36 2.37B
Tue, Dec 29, 2015 $2,060.54 $2,081.56 $2,060.54 $2,078.36 2.54B
Mon, Dec 28, 2015 $2,057.77 $2,057.77 $2,044.20 $2,056.50 2.49B
Thu, Dec 24, 2015 $2,063.52 $2,067.36 $2,058.73 $2,060.99 1.41B
Wed, Dec 23, 2015 $2,042.20 $2,064.73 $2,042.20 $2,064.29 3.48B
Tue, Dec 22, 2015 $2,023.15 $2,042.74 $2,020.49 $2,038.97 3.52B
Mon, Dec 21, 2015 $2,010.27 $2,022.90 $2,005.93 $2,021.15 3.76B
Fri, Dec 18, 2015 $2,040.81 $2,040.81 $2,005.33 $2,005.55 6.68B
Thu, Dec 17, 2015 $2,073.76 $2,076.37 $2,041.66 $2,041.89 4.33B

1 gt包-整洁的建立表格

R表格包太多太乱了让人不知道用哪个。gt包是Posit出品,秉承ggplot2理念,再加上它的扩展包gtsummary包(学术),gto包(导出到word,PPT),tablespan包(导出到Excel),会出现一统的趋势。

我们可以将展示表格视为仅用于输出,不希望再次将其用作输入。其他功能包括注释、表格元素样式和文本转换,这些都有助于更清晰地传达主题内容。

注意,我们要展示的表格最好不再参与之后的处理,而是要展示的最终结果。

1.1 gt包的简单表格入门

我们用islands数据集来演示gt包的基本用法。islands数据集实际为一个数字型的向量,包含世界各地岛屿的面积(平方英里)。我们将其转换为数据框以便使用gt包。

# Take the `islands` dataset and use some
# dplyr functionality to obtain the ten
# biggest islands in the world
islands_tbl <- tibble(name = names(islands), size = islands) |>
  slice_max(size, n = 10)
islands_tbl
# A tibble: 10 × 2
   name           size
   <chr>         <dbl>
 1 Asia          16988
 2 Africa        11506
 3 North America  9390
 4 South America  6795
 5 Antarctica     5500
 6 Europe         3745
 7 Australia      2968
 8 Greenland       840
 9 New Guinea      306
10 Borneo          280

接下来,我们使用gt()函数将数据框转换为gt表格对象。

# Create a gt table
gt_tbl <- gt(islands_tbl)
gt_tbl # print the gt table as html widget
name size
Asia 16988
Africa 11506
North America 9390
South America 6795
Antarctica 5500
Europe 3745
Australia 2968
Greenland 840
New Guinea 306
Borneo 280

在以上表格的基础上,根据 图 3gt_tbl对象添加对应的部分。

图 3: gt包的表格组成逻辑

大致包括一下几个部分。

1.2 表头(Table Header)

可选;包含标题和可能的副标题。gt::tab_header()我们可以使用md()函数在表头的部分使用markdown格式

# 直接添加标题
gt_tbl_header <- gt_tbl |>
  tab_header(
    title = "Large Landmasses of the World",
    subtitle = "The top ten largest are presented"
  )
gt_tbl_header
Large Landmasses of the World
The top ten largest are presented
name size
Asia 16988
Africa 11506
North America 9390
South America 6795
Antarctica 5500
Europe 3745
Australia 2968
Greenland 840
New Guinea 306
Borneo 280
# 使用markdown格式
gt_tbl_header <- gt_tbl |>
  tab_header(
    title = md("**Large Landmasses of the World**"), # 加粗
    subtitle = md("The *top ten* largest are presented") # 斜体
  )
gt_tbl_header
Large Landmasses of the World
The top ten largest are presented
name size
Asia 16988
Africa 11506
North America 9390
South America 6795
Antarctica 5500
Europe 3745
Australia 2968
Greenland 840
New Guinea 306
Borneo 280

1.4 存根与存根标题(the Stub and the Stub Head)

可选;包含行标签,可选择性地置于行组内,行组可带有行组标签,且在存在汇总时可能包含汇总标签。gt::tab_stubhead()

Stub表侧栏是表格左侧的区域,包含行标签,可能包含行组标签和汇总标签。这些子部分可以按行组顺序进行分组。表侧栏标题为描述表侧栏的标签提供位置。表侧栏是可选的,因为在某些情况下表侧栏并不实用(例如,之前展示的表格在没有表侧栏的情况下也能正常显示)。

可以简单的理解为行名列。
gt_tbl_stab <- islands_tbl |>
  gt(rowname_col = "name") |> # stub列
  tab_stubhead(label = "landmass") # stub列名
gt_tbl_stab
landmass size
Asia 16988
Africa 11506
North America 9390
South America 6795
Antarctica 5500
Europe 3745
Australia 2968
Greenland 840
New Guinea 306
Borneo 280

这里需要特别注意的一点是,在没有存根列时,表格有两列(列标签为 name 和 size ),但现在第 1 列(唯一的一列)是 size 。也可以理解为stub列是不算在gt表格的主体中的。

再添加了stub列后,我们就可以使用tab_row_group()函数将行划分为不同的组别,并在每个组的上方显示组标签。

# 添加gt表格各个组件
gt_tbl <- gt_tbl_stab |> # gt_tbl_stab是上一个步骤创建的表格对象,已经包含了stub列和stub标题
  tab_header(
    title = "Large Landmasses of the World",
    subtitle = "The top ten largest are presented"
  ) |>
  tab_source_note(
    source_note = "Source: The World Almanac and Book of Facts, 1975, page 406."
  ) |>
  tab_source_note(
    source_note = md(
      "Reference: McNeil, D. R. (1977) *Interactive Data Analysis*. Wiley."
    )
  ) |>
  tab_footnote(
    footnote = md("The **largest** by area."),
    locations = cells_body(columns = size, rows = largest)
  ) |>
  tab_footnote(
    footnote = "The lowest by population.",
    locations = cells_body(columns = size, rows = contains("arc"))
  )
gt_tbl
Large Landmasses of the World
The top ten largest are presented
landmass size
Asia 1 16988
Africa 11506
North America 9390
South America 6795
Antarctica 2 5500
Europe 3745
Australia 2968
Greenland 840
New Guinea 306
Borneo 280
1 The largest by area.
2 The lowest by population.
Source: The World Almanac and Book of Facts, 1975, page 406.
Reference: McNeil, D. R. (1977) Interactive Data Analysis. Wiley.
# 行分组
gt_tbl_rowgroup <- gt_tbl |>
  tab_row_group(label = md("**Continent**"), rows = 1:6) |>
  tab_row_group(label = "Country", rows = c("Australia", "Greenland")) |>
  tab_row_group(label = "Subregion", rows = c("New Guinea", "Borneo"))

gt_tbl_rowgroup
Large Landmasses of the World
The top ten largest are presented
landmass size
Subregion
New Guinea 306
Borneo 280
Country
Australia 2968
Greenland 840
Continent
Asia 1 16988
Africa 11506
North America 9390
South America 6795
Antarctica 2 5500
Europe 3745
1 The largest by area.
2 The lowest by population.
Source: The World Almanac and Book of Facts, 1975, page 406.
Reference: McNeil, D. R. (1977) Interactive Data Analysis. Wiley.
Tip

创建行分组的另一种方法是在输入数据表中包含一个分组名称的列。以我们上述的 islands_tbl 为例,若在适当行中设置包含 continentcountrysubregion 类别的 groupname 列,当使用 gt() 函数的 groupname_col 参数时(例如 gt(islands_tbl, rowname_col = "name", groupname_col = "groupname") |> ... ),就会生成行分组。这样就不再需要使用 tab_row_group()

这种在列中提供分组名称的策略有时更具优势,因为我们可以依赖诸如 dplyr 中的函数来生成类别(例如使用 case_when()if_else() )。

具体例子可参看gt()函数的帮助说明。

1.5 列标签(Column Labels)

包含列标签,可选择位于跨列标签下方。

表格的列标签部分至少包含列及其列标签。上一个示例中有一个单独的列: size 。正如在存根(Stub)中一样,我们可以创建称为跨列的分组,这些分组包含一个或多个列。tab_spanner()函数的功能正是如此。

我们使用包含更多列的airquality为例。

# Modify the `airquality` dataset by adding the year
# of the measurements (1973) and limiting to 10 rows
airquality_m <- airquality |> mutate(Year = 1973L) |> slice(1:10)
airquality_m
   Ozone Solar.R Wind Temp Month Day Year
1     41     190  7.4   67     5   1 1973
2     36     118  8.0   72     5   2 1973
3     12     149 12.6   74     5   3 1973
4     18     313 11.5   62     5   4 1973
5     NA      NA 14.3   56     5   5 1973
6     28      NA 14.9   66     5   6 1973
7     23     299  8.6   65     5   7 1973
8     19      99 13.8   59     5   8 1973
9      8      19 20.1   61     5   9 1973
10    NA     194  8.6   69     5  10 1973
# Create a display table using the `airquality_m`
# dataset; arrange columns into groups
gt_tbl_air <- airquality_m |>
  gt() |>
  tab_header(
    title = "New York Air Quality Measurements",
    subtitle = "Daily measurements in New York City (May 1-10, 1973)"
  ) |>
  tab_spanner(label = "Time", columns = c(Year, Month, Day)) |>
  tab_spanner(label = "Measurement", columns = c(Ozone, Solar.R, Wind, Temp))

gt_tbl_air
New York Air Quality Measurements
Daily measurements in New York City (May 1-10, 1973)
Measurement
Time
Ozone Solar.R Wind Temp Year Month Day
41 190 7.4 67 1973 5 1
36 118 8.0 72 1973 5 2
12 149 12.6 74 1973 5 3
18 313 11.5 62 1973 5 4
NA NA 14.3 56 1973 5 5
28 NA 14.9 66 1973 5 6
23 299 8.6 65 1973 5 7
19 99 13.8 59 1973 5 8
8 19 20.1 61 1973 5 9
NA 194 8.6 69 1973 5 10

以上gt_tbl_ari表格已经比较美观,但我们还可以进一步美化:

gt_tbl_air_modify <- gt_tbl_air |>
  cols_move_to_start(columns = c(Year, Month, Day)) |>
  cols_label(
    Ozone = html("Ozone, <br>ppbV"),
    Solar.R = html("Solar.R, <br>cal/m<sup>2</sup>"),
    Wind = html("Wind, <br>mph"),
    Temp = html("Temp, <br>&degF")
  )
gt_tbl_air_modify
New York Air Quality Measurements
Daily measurements in New York City (May 1-10, 1973)
Time
Measurement
Year Month Day Ozone,
ppbV
Solar.R,
cal/m2
Wind,
mph
Temp,
&degF
1973 5 1 41 190 7.4 67
1973 5 2 36 118 8.0 72
1973 5 3 12 149 12.6 74
1973 5 4 18 313 11.5 62
1973 5 5 NA NA 14.3 56
1973 5 6 28 NA 14.9 66
1973 5 7 23 299 8.6 65
1973 5 8 19 99 13.8 59
1973 5 9 8 19 20.1 61
1973 5 10 NA 194 8.6 69

cols_move_to_start()外,gt包还提供了其他一些函数来调整列的位置,例如cols_move_tocols_move_end()。这些函数允许我们根据需要将列移动到表格的不同位置,从而更好地组织和展示数据。

2 案例-gtcars数据集

让我们使用 gtcars 数据集制作一个展示表格。gtcars 数据集本质上是为 gt 时代现代化改造的 mtcars 。它是 gt 包的一部分,加载gt后可直接使用。在开始之前,为了更深入的了解gt,我们需要通过dplyr对数据进行预处理,减少表格的行数。

gtcars_8 <- gtcars |>
  group_by(ctry_origin) |>
  slice_head(n = 2) |>
  ungroup() |>
  filter(ctry_origin != "United Kingdom")
gtcars_8
# A tibble: 8 × 15
  mfr       model    year trim  bdy_style    hp hp_rpm   trq trq_rpm mpg_c mpg_h
  <chr>     <chr>   <dbl> <chr> <chr>     <dbl>  <dbl> <dbl>   <dbl> <dbl> <dbl>
1 BMW       6-Seri…  2016 640 … coupe       315   5800   330    1400    20    30
2 BMW       i8       2016 Mega… coupe       357   5800   420    3700    28    29
3 Ferrari   458 Sp…  2015 Base… coupe       597   9000   398    6000    13    17
4 Ferrari   458 Sp…  2015 Base  converti…   562   9000   398    6000    13    17
5 Acura     NSX      2017 Base… coupe       573   6500   476    2000    21    22
6 Nissan    GT-R     2016 Prem… coupe       545   6400   436    3200    16    22
7 Ford      GT       2017 Base… coupe       647   6250   550    5900    11    18
8 Chevrolet Corvet…  2016 Z06 … coupe       650   6400   650    3600    15    22
# ℹ 4 more variables: drivetrain <chr>, trsmn <chr>, ctry_origin <chr>,
#   msrp <dbl>

基于gtcars_8数据集,制作一个gt展示表格,并满足以下10项具体要求:

  1. 将汽车按照汽车制造商的原产国特征分组。
  2. 移除一些不需要展示的列。
  3. 将某些列合并为一个列组。
  4. 将货币数据格式化,并使用等宽字体以便阅读。
  5. 添加标题与副标题。
  6. 添加脚注以突出显示一些有趣的数据点,并解释数据中较为特殊的方面。
  7. 添加来源说明以提供数据的出处。
  8. 转换trsmn列(传统系统)编码,使其更清晰易懂。
  9. 根据基本条件设置某些单元格的格式。
  10. 突出显示为视为grand toures(豪华履行车)的汽车。

2.1 行分组

根据汽车制造商的原产国进行行分组。

  • 使用dplyr::group_by()函数对数据进行分组,按照ctry_origin列进行分组并排序。同时删除不想要展示的列,并建立新的列。
  • 将分好组的数据传递给gt()函数。
    • 此处可以使用rowname_col参数指定一个列作为行标签(例如之前建立的新列),也可以不指定行标签列,此时gt会自动创建一个默认的行标签列。
order_countries <- c("Germany", "Italy", "United States", "Japan") # 定义行分组的顺序

# 对数据进行分组、排序和预处理并创建gt表格
gtcars_8_grouped_tab <- gtcars_8 |>
  arrange(factor(ctry_origin, levels = order_countries), mfr, desc(msrp)) |>
  mutate(car = paste(mfr, model)) |> # 创建一个新的列car,将mfr和model列的内容合并为一个字符串
  select(-c(mfr, model)) |>
  group_by(ctry_origin) |>
  gt(rowname_col = "car") # 将新建立的car列作为行标签列
gtcars_8_grouped_tab
year trim bdy_style hp hp_rpm trq trq_rpm mpg_c mpg_h drivetrain trsmn msrp
Germany
BMW i8 2016 Mega World Coupe coupe 357 5800 420 3700 28 29 awd 6am 140700
BMW 6-Series 2016 640 I Coupe coupe 315 5800 330 1400 20 30 rwd 8am 77300
Italy
Ferrari 458 Speciale 2015 Base Coupe coupe 597 9000 398 6000 13 17 rwd 7a 291744
Ferrari 458 Spider 2015 Base convertible 562 9000 398 6000 13 17 rwd 7a 263553
United States
Chevrolet Corvette 2016 Z06 Coupe coupe 650 6400 650 3600 15 22 rwd 7m 88345
Ford GT 2017 Base Coupe coupe 647 6250 550 5900 11 18 rwd 7a 447000
Japan
Acura NSX 2017 Base Coupe coupe 573 6500 476 2000 21 22 awd 9a 156000
Nissan GT-R 2016 Premium Coupe coupe 545 6400 436 3200 16 22 awd 6a 101770

2.2 隐藏与移动部分列

  • 使用cols_hide()函数隐藏不需要展示的列。
  • 使用cols_move_to_start()函数将某些列移动到表格的开头。类似的函数还有cols_move()cols_move_end(),可以根据需要将列移动到表格的不同位置。
  • 值得注意的是,以上的操作均可以通过 dplyr::select() 实现。
# 隐藏不需要展示的列并移动某些列到表格的开头
gtcars_8_hide_move_tab <- gtcars_8_grouped_tab |>
  cols_hide(columns = c(drivetrain, bdy_style)) |>
  cols_move(columns = c(trsmn, mpg_c, mpg_h), after = "trim")
gtcars_8_hide_move_tab
year trim trsmn mpg_c mpg_h hp hp_rpm trq trq_rpm msrp
Germany
BMW i8 2016 Mega World Coupe 6am 28 29 357 5800 420 3700 140700
BMW 6-Series 2016 640 I Coupe 8am 20 30 315 5800 330 1400 77300
Italy
Ferrari 458 Speciale 2015 Base Coupe 7a 13 17 597 9000 398 6000 291744
Ferrari 458 Spider 2015 Base 7a 13 17 562 9000 398 6000 263553
United States
Chevrolet Corvette 2016 Z06 Coupe 7m 15 22 650 6400 650 3600 88345
Ford GT 2017 Base Coupe 7a 11 18 647 6250 550 5900 447000
Japan
Acura NSX 2017 Base Coupe 9a 21 22 573 6500 476 2000 156000
Nissan GT-R 2016 Premium Coupe 6a 16 22 545 6400 436 3200 101770

2.3 列分组

# 将 mpg_c 、 mpg_h 、 hp 、 hp_rpm 、 trq 、 trq_rpm 列放在 Performance 跨列标签下,其余列不分组
gtcars_8_column_grouping_tab <- gtcars_8_hide_move_tab |>
  tab_spanner(
    label = "Performance",
    columns = c(mpg_c, mpg_h, hp, hp_rpm, trq, trq_rpm)
  )
gtcars_8_column_grouping_tab
year trim trsmn
Performance
msrp
mpg_c mpg_h hp hp_rpm trq trq_rpm
Germany
BMW i8 2016 Mega World Coupe 6am 28 29 357 5800 420 3700 140700
BMW 6-Series 2016 640 I Coupe 8am 20 30 315 5800 330 1400 77300
Italy
Ferrari 458 Speciale 2015 Base Coupe 7a 13 17 597 9000 398 6000 291744
Ferrari 458 Spider 2015 Base 7a 13 17 562 9000 398 6000 263553
United States
Chevrolet Corvette 2016 Z06 Coupe 7m 15 22 650 6400 650 3600 88345
Ford GT 2017 Base Coupe 7a 11 18 647 6250 550 5900 447000
Japan
Acura NSX 2017 Base Coupe 9a 21 22 573 6500 476 2000 156000
Nissan GT-R 2016 Premium Coupe 6a 16 22 545 6400 436 3200 101770

2.4 和并列并添加标签

  • 使用cols_merge()函数将某些列合并为一个列。
    • cols_merge() 使用 col_1 列和 col_2 列。合并后,col_1 列将被保留,col_2 列将被删除。
    • pattern使用参数{1}{2}分别代表col_1col_2列的值。
    • 针对HTML表格,还可以使用html标签来调整合并后列的格式,例如<br>标签可以在合并后的列中创建换行。
    • 当使用<<>>pattern参数中的文本包裹起来时,表示当存在 NA 值时,移除双花括号内的所有内容。例如当我们发现一行中有两列的值都是NA时,与其让NA出现在展示的表格中,不如将本条目完全删除。
  • 使用cols_label()函数为新列添加标签。
注意,使用gt创建的表格最好直接用来展示,而不需要进行继续的加工。
gtcars_8_merge_columns_tab <- gtcars_8_column_grouping_tab |>
  cols_merge(columns = c(mpg_c, mpg_h), pattern = "<<{1}c<br>{2}h>>") |>
  cols_merge(columns = c(hp, hp_rpm), pattern = "{1}<br>@{2}rpm") |>
  cols_merge(columns = c(trq, trq_rpm), pattern = "{1}<br>@{2}rpm") |>
  cols_label(
    mpg_c = "MPG",
    hp = "HP",
    trq = "Torque",
    year = "Year",
    trim = "Trim",
    trsmn = "Transmission",
    msrp = "MSRP"
  )
gtcars_8_merge_columns_tab
Year Trim Transmission
Performance
MSRP
MPG HP Torque
Germany
BMW i8 2016 Mega World Coupe 6am 28c
29h
357
@5800rpm
420
@3700rpm
140700
BMW 6-Series 2016 640 I Coupe 8am 20c
30h
315
@5800rpm
330
@1400rpm
77300
Italy
Ferrari 458 Speciale 2015 Base Coupe 7a 13c
17h
597
@9000rpm
398
@6000rpm
291744
Ferrari 458 Spider 2015 Base 7a 13c
17h
562
@9000rpm
398
@6000rpm
263553
United States
Chevrolet Corvette 2016 Z06 Coupe 7m 15c
22h
650
@6400rpm
650
@3600rpm
88345
Ford GT 2017 Base Coupe 7a 11c
18h
647
@6250rpm
550
@5900rpm
447000
Japan
Acura NSX 2017 Base Coupe 9a 21c
22h
573
@6500rpm
476
@2000rpm
156000
Nissan GT-R 2016 Premium Coupe 6a 16c
22h
545
@6400rpm
436
@3200rpm
101770

2.5 使用格式化函数

  • 使用fmt_**()系列函数对数据进行格式化。如货币格式化函数fmt_currency()等。
  • 值得注意的是,我们在指定格式化列的时候,仍需要使用其原始列名,而不是展示的label列名。
gtcars_8_formatting_tab <- gtcars_8_merge_columns_tab |>
  fmt_currency(columns = msrp, currency = "USD", decimals = 0)
gtcars_8_formatting_tab
Year Trim Transmission
Performance
MSRP
MPG HP Torque
Germany
BMW i8 2016 Mega World Coupe 6am 28c
29h
357
@5800rpm
420
@3700rpm
$140,700
BMW 6-Series 2016 640 I Coupe 8am 20c
30h
315
@5800rpm
330
@1400rpm
$77,300
Italy
Ferrari 458 Speciale 2015 Base Coupe 7a 13c
17h
597
@9000rpm
398
@6000rpm
$291,744
Ferrari 458 Spider 2015 Base 7a 13c
17h
562
@9000rpm
398
@6000rpm
$263,553
United States
Chevrolet Corvette 2016 Z06 Coupe 7m 15c
22h
650
@6400rpm
650
@3600rpm
$88,345
Ford GT 2017 Base Coupe 7a 11c
18h
647
@6250rpm
550
@5900rpm
$447,000
Japan
Acura NSX 2017 Base Coupe 9a 21c
22h
573
@6500rpm
476
@2000rpm
$156,000
Nissan GT-R 2016 Premium Coupe 6a 16c
22h
545
@6400rpm
436
@3200rpm
$101,770

2.6 列对齐与样式变更

gtcars_8_alignment_styling_tab <- gtcars_8_formatting_tab |>
  cols_align(columns = c(mpg_c, hp, trq), align = "center") |>
  tab_style(
    style = cell_text(size = px(12)), # 设置字体大小为12像素
    locations = cells_body(columns = c(trim, trsmn, mpg_c, trq)) # 设置trim、trsmn、mpg_c和trq列的单元格文本样式
  )
gtcars_8_alignment_styling_tab
Year Trim Transmission
Performance
MSRP
MPG HP Torque
Germany
BMW i8 2016 Mega World Coupe 6am 28c
29h
357
@5800rpm
420
@3700rpm
$140,700
BMW 6-Series 2016 640 I Coupe 8am 20c
30h
315
@5800rpm
330
@1400rpm
$77,300
Italy
Ferrari 458 Speciale 2015 Base Coupe 7a 13c
17h
597
@9000rpm
398
@6000rpm
$291,744
Ferrari 458 Spider 2015 Base 7a 13c
17h
562
@9000rpm
398
@6000rpm
$263,553
United States
Chevrolet Corvette 2016 Z06 Coupe 7m 15c
22h
650
@6400rpm
650
@3600rpm
$88,345
Ford GT 2017 Base Coupe 7a 11c
18h
647
@6250rpm
550
@5900rpm
$447,000
Japan
Acura NSX 2017 Base Coupe 9a 21c
22h
573
@6500rpm
476
@2000rpm
$156,000
Nissan GT-R 2016 Premium Coupe 6a 16c
22h
545
@6400rpm
436
@3200rpm
$101,770

2.7 文本字体格式转换

  • 使用text_transform()函数对文本进行格式转换。
  • 通过 cells_body() 位置辅助函数定位数据单元格后,我们向 fn 参数提供一个函数,该函数处理文本向量并返回一个格式化的文本向量。对于 HTML 表格,返回的文本可以包含 HTML 标签以调整格式。
gtcars_8_text_transform_tab <- gtcars_8_alignment_styling_tab |>
  text_transform(
    locations = cells_body(columns = trsmn), # 定位trim列的单元格
    fn = function(x) {
      # The first character of `x` always
      # indicates the number of transmission speeds
      speed <- substr(x, 1, 1) # 提取trim列中每个值的第一个字符

      # We can carefully determine which transmission
      # type we have in `x` with a `dplyr::case_when()`
      # statement
      type <- dplyr::case_when(
        substr(x, 2, 3) == "am" ~ "Automatic/Maunal", # 如果trim列中每个值的第2和第3个字符是"am",则类型为"Automatic/Manual"
        substr(x, 2, 2) == "m" ~ "Manual", # 如果trim列中每个值的第2个字符是"m",则类型为"Manual"
        substr(x, 2, 2) == "a" ~ "Automatic", # 如果trim列中每个值的第2个字符是"a",则类型为"Automatic"
        substr(x, 2, 3) == "dd" ~ "Direct Drive" # 如果trim列中每个值的第2和第3个字符是"dd",则类型为"Direct Drive"
      )

      # Let's paste together the `speed` and `type`
      # vectors to create HTML text replacing `x`
      paste(speed, " Speed<br><em>", type, "</em>")
    }
  )
gtcars_8_text_transform_tab
Year Trim Transmission
Performance
MSRP
MPG HP Torque
Germany
BMW i8 2016 Mega World Coupe 6 Speed
Automatic/Maunal
28c
29h
357
@5800rpm
420
@3700rpm
$140,700
BMW 6-Series 2016 640 I Coupe 8 Speed
Automatic/Maunal
20c
30h
315
@5800rpm
330
@1400rpm
$77,300
Italy
Ferrari 458 Speciale 2015 Base Coupe 7 Speed
Automatic
13c
17h
597
@9000rpm
398
@6000rpm
$291,744
Ferrari 458 Spider 2015 Base 7 Speed
Automatic
13c
17h
562
@9000rpm
398
@6000rpm
$263,553
United States
Chevrolet Corvette 2016 Z06 Coupe 7 Speed
Manual
15c
22h
650
@6400rpm
650
@3600rpm
$88,345
Ford GT 2017 Base Coupe 7 Speed
Automatic
11c
18h
647
@6250rpm
550
@5900rpm
$447,000
Japan
Acura NSX 2017 Base Coupe 9 Speed
Automatic
21c
22h
573
@6500rpm
476
@2000rpm
$156,000
Nissan GT-R 2016 Premium Coupe 6 Speed
Automatic
16c
22h
545
@6400rpm
436
@3200rpm
$101,770

2.8 添加来源

gtcars_8_source_note_tab <- gtcars_8_text_transform_tab |>
  tab_source_note(source_note = "来源:Edmonds 网站内的多个页面。")
gtcars_8_source_note_tab
Year Trim Transmission
Performance
MSRP
MPG HP Torque
Germany
BMW i8 2016 Mega World Coupe 6 Speed
Automatic/Maunal
28c
29h
357
@5800rpm
420
@3700rpm
$140,700
BMW 6-Series 2016 640 I Coupe 8 Speed
Automatic/Maunal
20c
30h
315
@5800rpm
330
@1400rpm
$77,300
Italy
Ferrari 458 Speciale 2015 Base Coupe 7 Speed
Automatic
13c
17h
597
@9000rpm
398
@6000rpm
$291,744
Ferrari 458 Spider 2015 Base 7 Speed
Automatic
13c
17h
562
@9000rpm
398
@6000rpm
$263,553
United States
Chevrolet Corvette 2016 Z06 Coupe 7 Speed
Manual
15c
22h
650
@6400rpm
650
@3600rpm
$88,345
Ford GT 2017 Base Coupe 7 Speed
Automatic
11c
18h
647
@6250rpm
550
@5900rpm
$447,000
Japan
Acura NSX 2017 Base Coupe 9 Speed
Automatic
21c
22h
573
@6500rpm
476
@2000rpm
$156,000
Nissan GT-R 2016 Premium Coupe 6 Speed
Automatic
16c
22h
545
@6400rpm
436
@3200rpm
$101,770
来源:Edmonds 网站内的多个页面。

2.9 添加脚注并将代码推广至整个表格

  • 使用tab_footnote()函数添加以下脚注。
    1. identifying the car with the best gas mileage (city)
    2. identifying the car with the highest horsepower
    3. stating the currency of the MSRP
# Use dplyr functions to get the car with the best city gas mileage;
# this will be used to target the correct cell for a footnote
best_gas_mileage_city <- gtcars |>
  slice_max(mpg_c, n = 1) |>
  mutate(car = paste(mfr, model)) |>
  pull(car)

# Use dplyr functions to get the car with the highest horsepower;
# this will be used to target the correct cell for a footnote
highest_horsepower <- gtcars |>
  slice_max(hp, n = 1) |>
  mutate(car = paste(mfr, model)) |>
  pull(car)

# Create a display table with `gtcars`, using all of the previous
# statements piped together + additional `tab_footnote()` stmts

final_gtcars_tab <- gtcars |>
  arrange(factor(ctry_origin, levels = order_countries), mfr, desc(msrp)) |>
  mutate(car = paste(mfr, model)) |>
  select(-c(mfr, model)) |>
  group_by(ctry_origin) |>
  gt(rowname_col = "car") |>
  cols_hide(columns = c(drivetrain, bdy_style)) |>
  cols_move(columns = c(trsmn, mpg_c, mpg_h), after = "trim") |>
  tab_spanner(
    label = "Performance",
    columns = c(mpg_c, mpg_h, hp, hp_rpm, trq, trq_rpm)
  ) |>
  cols_merge(columns = c(mpg_c, mpg_h), pattern = "<<{1}c<br>{2}h>>") |>
  cols_merge(columns = c(hp, hp_rpm), pattern = "{1}<br>@{2}rpm") |>
  cols_merge(columns = c(trq, trq_rpm), pattern = "{1}<br>@{2}rpm") |>
  fmt_currency(columns = msrp, currency = "USD", decimals = 0) |> # 将msrp列格式化为货币格式,使用美元符号,并且不显示小数位
  cols_align(columns = c(mpg_c, hp, trq), align = "center") |>
  tab_style(
    style = cell_text(size = px(12)),
    locations = cells_body(columns = c(trim, trsmn, mpg_c, trq))
  ) |>
  text_transform(locations = cells_body(columns = trsmn), fn = function(x) {
    speed <- substr(x, 1, 1)

    type <- dplyr::case_when(
      substr(x, 2, 3) == "am" ~ "Automatic/Maunal",
      substr(x, 2, 2) == "m" ~ "Manual",
      substr(x, 2, 2) == "a" ~ "Automatic",
      substr(x, 2, 3) == "dd" ~ "Direct Drive"
    )

    paste(speed, " Speed<br><em>", type, "</em>")
  }) |>
  tab_source_note(source_note = "来源:Edmonds 网站内的多个页面。") |>
  tab_footnote(
    footnote = md("The highest horsepower of all the **gtcars**."),
    locations = cells_body(columns = hp, rows = car == highest_horsepower)
  ) |>
  tab_footnote(
    footnote = md("Best gas mileage (city) of all the **gtcars**."),
    locations = cells_body(columns = mpg_c, rows = car == best_gas_mileage_city)
  ) |>
  tab_footnote(
    footnote = "All price in U.S. dollars (USD).",
    locations = cells_column_labels(columns = msrp)
  ) |>
  cols_label(
    # 因为之前修改列均需要使用原始列名,所以将修改标签列的操作放在最后
    mpg_c = "MPG",
    hp = "HP",
    trq = "Torque",
    year = "Year",
    trim = "Trim",
    trsmn = "Transmission",
    msrp = "MSRP"
  )

final_gtcars_tab
Year Trim Transmission
Performance
MSRP1
MPG HP Torque
Germany
Audi R8 2015 4.2 (Manual) Coupe 6 Speed
Manual
11c
20h
430
@7900rpm
317
@4500rpm
$115,900
Audi S8 2016 Base Sedan 8 Speed
Automatic/Maunal
15c
25h
520
@5800rpm
481
@1700rpm
$114,900
Audi RS 7 2016 Quattro Hatchback 8 Speed
Automatic/Maunal
15c
25h
560
@5700rpm
516
@1750rpm
$108,900
Audi S7 2016 Prestige quattro Hatchback 7 Speed
Automatic
17c
27h
450
@5800rpm
406
@1400rpm
$82,900
Audi S6 2016 Premium Plus quattro Sedan 7 Speed
Automatic
18c
27h
450
@5800rpm
406
@1400rpm
$70,900
BMW i8 2016 Mega World Coupe 6 Speed
Automatic/Maunal
28c
29h2
357
@5800rpm
420
@3700rpm
$140,700
BMW M6 2016 Base Coupe 7 Speed
Automatic
15c
22h
560
@6000rpm
500
@1500rpm
$113,400
BMW M5 2016 Base Sedan 7 Speed
Automatic/Maunal
15c
22h
560
@6000rpm
500
@1500rpm
$94,100
BMW 6-Series 2016 640 I Coupe 8 Speed
Automatic/Maunal
20c
30h
315
@5800rpm
330
@1400rpm
$77,300
BMW M4 2016 Base Coupe 6 Speed
Manual
17c
24h
425
@5500rpm
406
@1850rpm
$65,700
Mercedes-Benz AMG GT 2016 S Coupe 7 Speed
Automatic
16c
22h
503
@6250rpm
479
@1750rpm
$129,900
Mercedes-Benz SL-Class 2016 SL400 Convertible 7 Speed
Automatic/Maunal
20c
27h
329
@5250rpm
354
@1600rpm
$85,050
Porsche 911 2016 Carrera Coupe 7 Speed
Manual
20c
28h
350
@7400rpm
287
@5600rpm
$84,300
Porsche Panamera 2016 Base Sedan 7 Speed
Automatic
18c
28h
310
@6200rpm
295
@3750rpm
$78,100
Porsche 718 Boxster 2017 Base Convertible 6 Speed
Manual
21c
28h
300
@6500rpm
280
@1950rpm
$56,000
Porsche 718 Cayman 2017 Base Coupe 6 Speed
Manual
20c
29h
300
@6500rpm
280
@1950rpm
$53,900
Italy
Ferrari LaFerrari 2015 Base Coupe 7 Speed
Automatic
12c
16h
949
@9000rpm3
664
@6750rpm
$1,416,362
Ferrari F12Berlinetta 2015 Base Coupe 7 Speed
Automatic
11c
16h
731
@8250rpm
509
@6000rpm
$319,995
Ferrari GTC4Lusso 2017 Base Coupe 7 Speed
Automatic
12c
17h
680
@8250rpm
514
@5750rpm
$298,000
Ferrari FF 2015 Base Coupe 7 Speed
Automatic
11c
16h
652
@8000rpm
504
@6000rpm
$295,000
Ferrari 458 Speciale 2015 Base Coupe 7 Speed
Automatic
13c
17h
597
@9000rpm
398
@6000rpm
$291,744
Ferrari 458 Spider 2015 Base 7 Speed
Automatic
13c
17h
562
@9000rpm
398
@6000rpm
$263,553
Ferrari 488 GTB 2016 Base Coupe 7 Speed
Automatic
15c
22h
661
@8000rpm
561
@3000rpm
$245,400
Ferrari 458 Italia 2014 Base Coupe 7 Speed
Automatic
13c
17h
562
@9000rpm
398
@6000rpm
$233,509
Ferrari California 2015 Base Convertible 7 Speed
Automatic
16c
23h
553
@7500rpm
557
@4750rpm
$198,973
Lamborghini Aventador 2015 LP 700-4 Coupe 7 Speed
Automatic
11c
18h
700
@8250rpm
507
@5500rpm
$397,500
Lamborghini Huracan 2015 LP 610-4 Coupe 7 Speed
Automatic
16c
20h
610
@8250rpm
413
@6500rpm
$237,250
Lamborghini Gallardo 2014 LP 550-2 Coupe 6 Speed
Automatic
12c
20h
550
@8000rpm
398
@6500rpm
$191,900
Maserati Granturismo 2016 Sport Coupe 6 Speed
Automatic/Maunal
13c
21h
454
@7600rpm
384
@4750rpm
$132,825
Maserati Quattroporte 2016 S Sedan 8 Speed
Automatic/Maunal
16c
23h
404
@5500rpm
406
@1500rpm
$99,900
Maserati Ghibli 2016 Base Sedan 8 Speed
Automatic/Maunal
17c
24h
345
@5250rpm
369
@1750rpm
$70,600
United States
Chevrolet Corvette 2016 Z06 Coupe 7 Speed
Manual
15c
22h
650
@6400rpm
650
@3600rpm
$88,345
Dodge Viper 2017 GT Coupe 6 Speed
Manual
12c
19h
645
@5000rpm
600
@5000rpm
$95,895
Ford GT 2017 Base Coupe 7 Speed
Automatic
11c
18h
647
@6250rpm
550
@5900rpm
$447,000
Tesla Model S 2017 75D 1 Speed
Direct Drive
259
@6100rpm
243
@NArpm
$74,500
Japan
Acura NSX 2017 Base Coupe 9 Speed
Automatic
21c
22h
573
@6500rpm
476
@2000rpm
$156,000
Nissan GT-R 2016 Premium Coupe 6 Speed
Automatic
16c
22h
545
@6400rpm
436
@3200rpm
$101,770
United Kingdom
Aston Martin Vanquish 2016 Base Coupe 8 Speed
Automatic/Maunal
13c
21h
568
@6650rpm
465
@5500rpm
$287,250
Aston Martin DB11 2017 Base Coupe 8 Speed
Automatic/Maunal
15c
21h
608
@6500rpm
516
@1500rpm
$211,195
Aston Martin Rapide S 2016 Base Sedan 8 Speed
Automatic/Maunal
14c
21h
552
@6650rpm
465
@5500rpm
$205,300
Aston Martin Vantage 2016 V8 GT (Manual) Coupe 6 Speed
Manual
13c
19h
430
@7300rpm
361
@5000rpm
$103,300
Bentley Continental GT 2016 V8 Coupe 8 Speed
Automatic/Maunal
15c
25h
500
@6000rpm
487
@1700rpm
$198,500
Jaguar F-Type 2016 Base (Manual) Coupe 6 Speed
Manual
16c
24h
340
@6500rpm
332
@3500rpm
$65,000
Lotus Evora 2017 2+2 Coupe 6 Speed
Manual
16c
24h
400
@7000rpm
302
@3500rpm
$91,900
McLaren 570 2016 Base Coupe 7 Speed
Automatic
16c
23h
570
@7500rpm
443
@5000rpm
$184,900
Rolls-Royce Dawn 2016 Base Convertible 8 Speed
Automatic
12c
19h
563
@5250rpm
575
@1500rpm
$335,000
Rolls-Royce Wraith 2016 Base Coupe 8 Speed
Automatic
13c
21h
624
@5600rpm
590
@1500rpm
$304,350
1 All price in U.S. dollars (USD).
2 Best gas mileage (city) of all the gtcars.
3 The highest horsepower of all the gtcars.
来源:Edmonds 网站内的多个页面。