如何用gtExtras建立一个Kaggle排行榜 ?

293 阅读7分钟

gtExtras 包是由Tom Mock 编写的,它是一个高级包装,围绕着神奇的gt 包来创建漂亮的表格。自从一年前发现gt ,我就广泛地使用它。它现在是我在表格中展示数据的首选包。除了gtgtExtras ,我们只需要一些基本的tidyverse库。

libs <- c('dplyr', 'tibble',    # wrangling
          'tidyr', 'stringr',   # wrangling
          'readr',              # input
          'gt', 'gtExtras')     # tables
invisible(lapply(libs, library, character.only = TRUE))

这个排行榜的数据是由各个评委的分数汇总而成的。这些详细的分数将保持机密,但以其汇总的形式构成了公共排行榜。在这里,我正在阅读汇总表。

scores_total <- read_csv("../../static/files/gems_comp_scores_total.csv", col_types = cols())

一组小的辅助变量定义了一些Kaggle特有的颜色。如果你在这个平台上很活跃,那么这些颜色对你来说应该很熟悉。我喜欢在与Kaggle相关的分析中使用这些颜色,比如我自己的Hidden Gems EDA笔记本

kaggle_blue <- "#008abc"
kaggle_gold <- "#fed348"
kaggle_silver <- "#e9e9e9"
kaggle_bronze <- "#f0ba7c"

这就是目前的设置。我将在此过程中解释另一个准备方面。现在,让我们从最后开始。这是产生我们最终表格的完整代码。

avatars <- tibble(
  avatar = fs::dir_ls("../../static/pics/gems_comp_img/", glob = "*.*")
) %>% 
  separate(avatar, sep = "/", into = c("a", "b", "c", "d", "e", "user"), remove = FALSE) %>% 
  mutate(user = str_remove(user, ".jpg")) %>% 
  mutate(user = str_remove(user, ".png")) %>% 
  select(-a, -b, -c, -d, -e)


scores_total %>% 
  rownames_to_column(var = "rank") %>% 
  mutate(perc = total/(7*5*5) * 100) %>% 
  left_join(avatars, by = "user") %>% 
  select(rank, avatar, author, total, perc) %>% 
  gt() %>% 
  gt_img_rows(avatar, img_source = "local") %>% 
  gt_plt_bar_pct(column = perc, scaled = TRUE, fill = kaggle_blue) %>%
  gt_highlight_rows(rows = 1, font_weight = "normal", fill = kaggle_gold) %>% 
  gt_highlight_rows(rows = 2, font_weight = "normal", fill = kaggle_silver) %>% 
  gt_highlight_rows(rows = 3, font_weight = "normal", fill = kaggle_bronze) %>% 
  tab_header(
    title = md("**Kaggle Hidden Gems Competition - Final Results**"),
    subtitle = html(str_c("<em>A 2022 Notebooks Competition scored by Community Judges </em>"))
    ) %>% 
  tab_style(
    style = cell_text(size = px(18), weight = "bold", style = "italic"),
    locations = cells_body(
      columns = c(author)
    )
  ) %>% 
  tab_style(
    style = cell_text(size = px(18), weight = "bold"),
    locations = cells_body(
      columns = c(total, rank)
    )
  ) %>% 
  cols_label(
    rank = "Rank",
    avatar = "",
    author = "Notebook Author",
    total = "Final Score",
    perc = "(vs max possible score)"
  ) %>%
  opt_row_striping()

我希望你和我一样喜欢这个表。gtExtras ,在用相对较少的代码行建立这个表的过程中帮助很大。我印象非常深刻。表格本身列出了作者的最终排名,以及他们的名字、个人照片和分数。分数以绝对分数和相对于最大可能分数的柱状图表示。对于前三名的作者,有一个使用Kaggle颜色的金-银-铜的阴影。现在让我们来看看我们是怎么做到的。

我们从标准gt 格式的原始输入表开始。

scores_total %>% 
  select(author, total) %>% 
  gt()
作者总数
Leonie153.0
米歇尔-博加茨149.5
布库恩139.5
舒伯特-德-阿布雷乌132.0
阿比尔-埃尔塔伊夫102.0
Karthik81.0
谭雅-达亚南德77.5
GSD64.0
斯拉夫亚-耶拉普拉加达55.0

可以说,这是一个干净但相当朴素的表格。向上滚动可以看到与最终表格的对比。在下一步中,我们将添加一些基本的gt ,包括标题和副标题、列名和行的条纹等样式。我们还将已经隐含在表格中的最终排名作为一个新的rank

scores_total %>% 
  select(author, total) %>% 
  rownames_to_column(var = "rank") %>% 
  gt() %>% 
  tab_header(
    title = md("**Kaggle Hidden Gems Competition - Final Results**"),
    subtitle = html(str_c("<em>A Notebooks Competition scored by Community Judges </em>"))
    ) %>% 
  cols_label(
    rank = "Rank",
    author = "Notebook Author",
    total = "Final Score"
  ) %>%
  opt_row_striping()
Kaggle隐藏宝石竞赛 - 最终结果
由社区评委打分的笔记本竞赛
---
排名笔记本作者最终得分
---------
1李奥妮153.0
2米歇尔-博加茨149.5
3布库恩139.5
4舒伯特-德-阿布雷乌132.0
5阿比尔-埃尔塔伊夫102.0
6卡尔蒂克81.0
7谭雅-达亚南德77.5
8GSD64.0
9斯拉夫亚-耶拉普拉加达55.0

到目前为止,还不错。这通常是我在基本EDA项目中使用的表格的格式化程度。但这是一个特殊的场合,所以让我们在这里多走一步。首先:颜色。金-银-铜的色调是通过gt_highlight_rows函数添加的。你可以看到,这里的参数非常简单:我们指定了行,填充颜色,还可以控制字体。

scores_total %>% 
  select(author, total) %>% 
  rownames_to_column(var = "rank") %>% 
  gt() %>% 
  gt_highlight_rows(rows = 1, font_weight = "normal", fill = kaggle_gold) %>% 
  gt_highlight_rows(rows = 2, font_weight = "normal", fill = kaggle_silver) %>% 
  gt_highlight_rows(rows = 3, font_weight = "normal", fill = kaggle_bronze) %>% 
  tab_header(
    title = md("**Kaggle Hidden Gems Competition - Final Results**"),
    subtitle = html(str_c("<em>A Notebooks Competition scored by Community Judges </em>"))
    ) %>% 
  cols_label(
    rank = "Rank",
    author = "Notebook Author",
    total = "Final Score"
  ) %>%
  opt_row_striping()
Kaggle隐藏宝石竞赛 - 最终结果
由社区评委打分的笔记本竞赛
---
排名笔记本作者最终得分
---------
1李奥妮153.0
2米歇尔-博加茨149.5
3布库恩139.5
4舒伯特-德-阿布雷乌132.0
5阿比尔-埃尔塔伊夫102.0
6卡尔蒂克81.0
7谭雅-达亚南德77.5
8GSD64.0
9斯拉夫亚-耶拉普拉加达55.0

接下来,我们要把分数与最大可能分数的百分比作为横条加入。这与表格中的文字和数字形成了一个很好的视觉对比。打分系统在7位评委的5个类别中最多可得5分,共175分。首先,我们像往常一样用mutate ,计算出百分比。然后我们用gt_plt_bar_pct将百分比显示为条形图。

scores_total %>% 
  select(author, total) %>% 
  rownames_to_column(var = "rank") %>% 
  mutate(perc = total/(7*5*5) * 100) %>% 
  gt() %>% 
  gt_plt_bar_pct(column = perc, scaled = TRUE, fill = kaggle_blue) %>%
  gt_highlight_rows(rows = 1, font_weight = "normal", fill = kaggle_gold) %>% 
  gt_highlight_rows(rows = 2, font_weight = "normal", fill = kaggle_silver) %>% 
  gt_highlight_rows(rows = 3, font_weight = "normal", fill = kaggle_bronze) %>% 
  tab_header(
    title = md("**Kaggle Hidden Gems Competition - Final Results**"),
    subtitle = html(str_c("<em>A Notebooks Competition scored by Community Judges </em>"))
    ) %>% 
  cols_label(
    rank = "Rank",
    author = "Notebook Author",
    total = "Final Score",
    perc = "(vs max possible score)"
  ) %>%
  opt_row_striping()
Kaggle隐藏宝石竞赛 - 最终结果
由社区评委打分的笔记本竞赛
---
排名笔记本作者最终得分(与可能的最高分相比)
------------
1李安153.0
2米歇尔-博加茨149.5
3布库恩139.5
4舒伯特-德-阿布雷乌132.0
5阿比尔-埃尔塔伊夫102.0
6卡尔蒂克81.0
7谭雅-达亚南德77.5
8GSD64.0
9斯拉夫亚-耶拉普拉加达55.0

好了,我们越来越接近我们的最终目标了。最后一个主要元素将是个人资料图片。当我看到gtExtras为表格添加图片的例子时,我真的很兴奋。在Kaggle上,你为你的个人资料设置的图片会作为你的头像出现在你创建或评论的几乎所有地方。许多多产的Kaggle用户很容易被他们的头像所识别。因此,我想把这些头像添加到表格中,不仅仅是作为一个不同的视觉元素,也是为了加强与各个Kaggler的联系。

你可以到任何一个Kaggler的资料中去看他们的头像图片的全尺寸版本。这是我的个人资料。这些图片在Kaggle那边的存储方式使得通过脚本访问它们有点困难(但我们可能会在以后的文章中研究这个问题)。目前,我正在手动下载我们九个参赛者的图片,并将它们存储在一个名为gems_comp_img 的文件夹中。这些是该文件夹的内容。

fs::dir_ls("../../static/pics/gems_comp_img/", glob = "*.*")
## ../../static/pics/gems_comp_img/abireltaief.jpg
## ../../static/pics/gems_comp_img/ambarish.jpg
## ../../static/pics/gems_comp_img/gsdeepakkumar.jpg
## ../../static/pics/gems_comp_img/iamleonie.jpg
## ../../static/pics/gems_comp_img/karthikrg.png
## ../../static/pics/gems_comp_img/michau96.jpg
## ../../static/pics/gems_comp_img/spitfire2nd.jpg
## ../../static/pics/gems_comp_img/sravyaysk.png
## ../../static/pics/gems_comp_img/tanyadayanand.jpg

现在,我用Kaggle用户名为图片命名,使事情变得简单了一些。这就是输入表中的user 列。这将使我们能够把这个图片列表加入到我们的分数表中。首先,我们创建一个名为avatars 的辅助表,在这里存储图片的链接,同时使用tidyr 工具separate ,解析出用户名称。

avatars <- tibble(
  avatar = fs::dir_ls("../../static/pics/gems_comp_img/", glob = "*.*")
) %>% 
  separate(avatar, sep = "/", into = c("a", "b", "c", "d", "e", "user"), remove = FALSE) %>% 
  mutate(user = str_remove(user, ".jpg")) %>% 
  mutate(user = str_remove(user, ".png")) %>% 
  select(-a, -b, -c, -d, -e)

avatars %>% 
  gt() %>%
  opt_row_striping()
头像用户
././static/pics/gems_comp_img/abireltaief.jpgabireltaief
..././static/pics/gems_comp_img/ambarish.jpg安巴里什
..././static/pics/gems_comp_img/gsdeepakkumar.jpggsdeepakkumar
..././static/pics/gems_comp_img/iamleonie.jpgiamleonie
././static/pics/gems_comp_img/karthikrg.png姜文
..././static/pics/gems_comp_img/michau96.jpgmichau96
././static/pics/gems_comp_img/spitfire2nd.jpg吐火机2nd
..././static/pics/gems_comp_img/sravyaysk.png薛明
..././static/pics/gems_comp_img/tanyadayanand.jpgtanyadayanand

现在我们可以加入这些表格,并将图片添加到我们的排行榜上所有在表列中显示图片的复杂性都由gt_img_rows来处理。真是不可思议!只有两行用于连接和格式化该列。第三行是次要的,为这些图片去掉了列的标题。

scores_total %>% 
  rownames_to_column(var = "rank") %>% 
  mutate(perc = total/(7*5*5) * 100) %>% 
  left_join(avatars, by = "user") %>% 
  select(rank, avatar, author, total, perc) %>% 
  gt() %>% 
  gt_img_rows(avatar, img_source = "local") %>% 
  gt_plt_bar_pct(column = perc, scaled = TRUE, fill = kaggle_blue) %>%
  gt_highlight_rows(rows = 1, font_weight = "normal", fill = kaggle_gold) %>% 
  gt_highlight_rows(rows = 2, font_weight = "normal", fill = kaggle_silver) %>% 
  gt_highlight_rows(rows = 3, font_weight = "normal", fill = kaggle_bronze) %>% 
  tab_header(
    title = md("**Kaggle Hidden Gems Competition - Final Results**"),
    subtitle = html(str_c("<em>A 2022 Notebooks Competition scored by Community Judges </em>"))
    ) %>% 
  cols_label(
    rank = "Rank",
    avatar = "",
    author = "Notebook Author",
    total = "Final Score",
    perc = "(vs max possible score)"
  ) %>%
  opt_row_striping()

简短的提醒:如果你使用fmt_markdown(columns = TRUE) 来设计你的表列,那么这似乎会与gt_img_rows 发生冲突。这可能是有道理的,因为图片链接可能会受到markdown格式的影响。但是我花了一些时间才搞清楚为什么我的图片不能工作,所以我在这里加入这个警告,以节省你的时间,如果你有类似的问题。而且,也许有一种方法可以让fmt_markdowngt_img_rows 共存;如果你找到了方法,请告诉我。

在这一点上,我们的排行榜实际上已经完成了。所有的信息和视觉元素都在那里。但是,作为最后的润色,我将添加一些文本格式,以确保那些作者的名字和分数不会过多地融入我们的头像和分数条旁边的背景中。这是最后的抛光步骤,让我们在开始时就能看到我们的表格。

我使用tab_style ,一个gt 命令,来增加字体的大小,并使其变成粗体,如果是作者姓名,也是斜体。

scores_total %>% 
  rownames_to_column(var = "rank") %>% 
  mutate(perc = total/(7*5*5) * 100) %>% 
  left_join(avatars, by = "user") %>% 
  select(rank, avatar, author, total, perc) %>% 
  gt() %>% 
  gt_img_rows(avatar, img_source = "local") %>% 
  gt_plt_bar_pct(column = perc, scaled = TRUE, fill = kaggle_blue) %>%
  gt_highlight_rows(rows = 1, font_weight = "normal", fill = kaggle_gold) %>% 
  gt_highlight_rows(rows = 2, font_weight = "normal", fill = kaggle_silver) %>% 
  gt_highlight_rows(rows = 3, font_weight = "normal", fill = kaggle_bronze) %>% 
  tab_header(
    title = md("**Kaggle Hidden Gems Competition - Final Results**"),
    subtitle = html(str_c("<em>A 2022 Notebooks Competition scored by Community Judges </em>"))
    ) %>% 
  tab_style(
    style = cell_text(size = px(18), weight = "bold", style = "italic"),
    locations = cells_body(
      columns = c(author)
    )
  ) %>% 
  tab_style(
    style = cell_text(size = px(18), weight = "bold"),
    locations = cells_body(
      columns = c(total, rank)
    )
  ) %>% 
  cols_label(
    rank = "Rank",
    avatar = "",
    author = "Notebook Author",
    total = "Final Score",
    perc = "(vs max possible score)"
  ) %>%
  opt_row_striping()

就这样!我们从一个普通的表格变成了一个排行榜的设计,我认为这值得我组织的第一个Kaggle(笔记本)比赛。gtgtExtras 的组合令人印象深刻,我希望它能为你自己的表格造型项目提供动力。