Язык R

и его применение в биоинформатике

Лекция 7

Анна Валяева

13 октября 2023

Тепловая карта

Тепловая карта

  • geom_tile() из ggplot2
  • ggheatmap() из ggheatmap
  • heatmap.2() из gplots
  • pheatmap() из pheatmap
  • Heatmap() из ComplexHeatmap

Тепловая карта корреляций:

  • corrplot() corrplot
  • cor_plot() rstatix

Данные

lemurs
# A tibble: 51 × 6
   name           sex   weight_1 weight_2 weight_3 birth_type
   <chr>          <chr>    <dbl>    <dbl>    <dbl> <chr>     
 1 Nosferatu      M         2860     2505     2930 wild      
 2 Poe            M         2700     2610     2680 wild      
 3 Samantha       F         2242     2360     2415 wild      
 4 Annabel Lee    F          944     1180     1689 captive   
 5 Mephistopheles M         2760     2520     2620 wild      
 6 Endora         F         2600     2360     2645 wild      
 7 Ozma           F         2500     2440     2620 wild      
 8 Morticia       F         2700     2550     2255 wild      
 9 Blue Devil     M         1330     1820     2460 captive   
10 Goblin         M         1180     1460     1150 captive   
# ℹ 41 more rows

geom_tile() из ggplot2

lemurs %>% 
  # Преобразовали датафрейм в более длинный формат
  pivot_longer(cols = starts_with("weight"), names_to = "weight_date") %>% 
  ggplot(aes(x = weight_date, y = name, fill = value, color = "NA")) +     
  geom_tile() +
  # Задали градиент цвета для отображения веса лемуров, указали цвет для `NA`
  scale_fill_gradient(                                                     
    low = "#fefae0", high = "#bc6c25", na.value = "#606c38",               
    labels = scales::number) +  
  # Добавили легенду для обозначения `NA`, настроили расположение легенд
  scale_color_manual(values = "black", labels = "Missing value") +         
  guides(                                                                  
    fill = guide_colorbar(order = 1),                                      
    color = guide_legend(override.aes = list(fill = "#606c38"),            
                         title = "", order = 2)) +                         
  scale_x_discrete(labels = 1:3) +                                         
  labs(x = "№ of measurment", y = "", fill = "Body mass (g)") +            
  theme(                                                                   
    panel.background = element_rect(fill = "transparent"),                 
    axis.text = element_text(color = "black"))                             

geom_tile() из ggplot2

Нужна матрица

lemurs <- drop_na(lemurs)
lemurs_mtx <- lemurs %>% select(where(is.numeric)) %>% as.matrix()
rownames(lemurs_mtx) <- lemurs$name

lemurs_mtx[1:5,]
               weight_1 weight_2 weight_3
Nosferatu          2860     2505     2930
Poe                2700     2610     2680
Samantha           2242     2360     2415
Annabel Lee         944     1180     1689
Mephistopheles     2760     2520     2620

pheatmap

# install.packages("pheatmap")
library(pheatmap)

pheatmap(lemurs_mtx, cluster_cols = FALSE, cluster_rows = TRUE)

Нормированные величины

pheatmap(lemurs_mtx, cluster_cols = FALSE, cluster_rows = TRUE,
         scale = "row")

Аннотации

  • должны быть в виде датафрема
  • имена строк датафрема должны совпадать с именами строк/столбцов матрицы
  • цвета задаются с помощью списка
ann <- lemurs %>% select(sex, birth_type) %>% as.data.frame()
rownames(ann) <- lemurs$name

# Цветовая палитра
ann_color <- list(sex = c("M" = "#fff3b0", "F" = "#e09f3e"),
                  birth_type = c("wild" = "#94d2bd", "captive" = "#0a9396"))

pheatmap

pheatmap(lemurs_mtx,                                            
         cluster_cols = FALSE, cluster_rows = TRUE,             
         annotation_row = ann, annotation_colors = ann_color,   
         color = colorRampPalette(c("#d9ed92", "#1a759f"))(50), 
         border_color = "grey10", labels_col = 1:3)             

ComplexHeatmap

# install.packages("ComplexHeatmap")
library(ComplexHeatmap)

Heatmap(lemurs_mtx) 

ComplexHeatmap - цвета

col_fun <- circlize::colorRamp2(c(-1, 0, 1), c("#d9ed92", "#ffffff", "#1a759f")) 

lemurs_mtx_scaled <- t(scale(t(lemurs_mtx)))                                     

Heatmap(lemurs_mtx_scaled, name = "Z-score",                                    
        col = col_fun, column_title = "Green-Blue palette")                      

Кластеризация

Heatmap(lemurs_mtx_scaled, name = "Z-score", 
        col = col_fun, column_title = "No clustering",
        cluster_rows = FALSE, cluster_columns = FALSE)

Дендрограммы

Heatmap(lemurs_mtx_scaled, name = "Z-score", 
        col = col_fun,  column_title = "Dendrogram on the right", 
        cluster_columns = FALSE,
        row_dend_side = "right", row_dend_width = unit(3, "cm"))

Аннотации

  • создаются с помощью функций rowAnnotation(), columnAnnotation() или HeatmapAnnotation()
  • цвета задаются с помощью списка
ra <- rowAnnotation(sex = ann$sex, birth_type = ann$birth_type,
  col = list(sex = c("M" = "#fff3b0", "F" = "#e09f3e"),
             birth_type = c("wild" = "#95b8d1", "captive" = "#b8e0d2")))

Аннотации

Heatmap(lemurs_mtx_scaled, name = "Z-score", 
        col = col_fun, column_title = "Aye-aye body mass",
        cluster_columns = FALSE, right_annotation = ra) 

Визуализация множеств

Диаграмма Венна

Визуализация “отношений” между 2-4 множествами объектов

Пакеты:

  • VennDiagram
  • eulerr
  • ggVennDiagram
  • ggvenn

Пример - данные про кулинарные рецепты

recipes
# A tibble: 428,275 × 5
   recipe_id cuisine ingredients                        course diet          
       <dbl> <chr>   <chr>                              <chr>  <chr>         
 1         0 spanish mussels                            Lunch  Non Vegetarian
 2         0 spanish ground black pepper                Lunch  Non Vegetarian
 3         0 spanish garlic cloves                      Lunch  Non Vegetarian
 4         0 spanish saffron threads                    Lunch  Non Vegetarian
 5         0 spanish olive oil                          Lunch  Non Vegetarian
 6         0 spanish stewed tomatoes                    Lunch  Non Vegetarian
 7         0 spanish arborio rice                       Lunch  Non Vegetarian
 8         0 spanish minced onion                       Lunch  Non Vegetarian
 9         0 spanish medium shrimp                      Lunch  Non Vegetarian
10         0 spanish fat free less sodium chicken broth Lunch  Non Vegetarian
# ℹ 428,265 more rows

Искусственный датасет, за основу взят Kaggle - Recipe Ingredients Dataset

Задача для диаграммы Венна

Сколько рецептов сочетают в себе и томаты, и молоко?

  1. Создаем вектор с ID рецептов, в которых есть томаты:
tomatoes <- recipes %>% filter(ingredients == "tomatoes") %>% pull(recipe_id) 
length(tomatoes)
[1] 3058
  1. Создаем вектор с ID рецептов, в которых есть молоко:
milk <- recipes %>% filter(ingredients == "milk") %>% pull(recipe_id)
length(milk)
[1] 2263
  1. Сколько в этих векторах общих элементов?
intersect(tomatoes, milk) %>% length()
[1] 78

VennDiagram

  • На вход - список из векторов
  • На выход - файл с диаграммой в заданном формате
# install.packages("VennDiagram")
library(VennDiagram)

venn.diagram(
  x = list(tomatoes, milk),
  category.names = c("Tomatoes" , "Milk"),
  filename = "tomatoes_milk.png",
  imagetype = "png",
  height = 5, 
  width = 5, 
  units = "cm",
  resolution = 300,
  col = c("#e63946", "#a8dadc"),
  fill = c(alpha("#e63946", .4), alpha("#a8dadc", .4)),
  cex = 0.5,
  fontfamily = "sans",
  cat.cex = 0.5,
  cat.pos = c(-27, 27),
  cat.dist = c(0.055, 0.055),
  cat.fontfamily = "sans")

ggVennDiagram

# install.packages("ggVennDiagram")
library("ggVennDiagram")

ggVennDiagram(list(tomatoes, milk), category.names = c("Tomatoes", "Milk")) +
  scale_fill_gradient(low = "white", high = "tomato2")

eulerr

# install.packages("eulerr")
library(eulerr)

plot(
  euler(list(Tomatoes = tomatoes, Milk = milk, Eggs = eggs), 
        shape = "ellipse"), quantities = TRUE)

Когда категорий много…

Eulerr

ggVennDiagram

Когда категорий много…

UpSet plot

Пакеты:

  • UpSetR
  • ComplexHeatmap
  • ggupset

UpSetR

# install.packages("UpSetR")
library(UpSetR)

upset(fromList(list(Tomatoes = tomatoes, Milk = milk, 
                    Eggs = eggs, Onions = onions, 
                    Garlic = garlic, carrots = carrots)), 
      order.by = "freq",
      sets.bar.color = c("#e29578", "#ffddd2", "#f1faee", "#e63946", "#fb8500"),
      main.bar.color = "#147d4b", matrix.color = "#147d4b", shade.color = "#ffc700")

Alluvial plot 🏠

Визуализация нескольких категориальных признаков

  • axis - оси - столбцы, составленные из категориальных переменных
  • stata - страты - значения категориальных переменных в виде ячеек в столбцах
  • alluvium - “поток” между стратами, состоит из потоков (flow, если страт несколько)

ggalluvial 🏠

Код

# install.packages("ggalluvial")
library(ggalluvial)

recipes %>% select(-ingredients) %>% distinct() %>% 
  count(cuisine, course, diet) %>% 
  ggplot(aes(y = n, axis1 = course, axis2 = diet)) +
  geom_alluvium(aes(fill = cuisine)) +
  geom_stratum() +
  geom_label(stat = "stratum", aes(label = after_stat(stratum))) +
  scale_fill_manual(values = colorRampPalette(c("#fe938c", "#ead2ac", "#4281a4"))(20)) +
  theme_void() + theme(legend.position = "none")

Alluvial plot - ggsankey 🏠

Alluvial plot - ggsankey 🏠

Код

# install.packages("devtools")
# devtools::install_github("davidsjoberg/ggsankey")
library(ggsankey)

recipes %>% select(-ingredients) %>% distinct() %>% 
  make_long(cuisine, course, diet) %>% 
  ggplot(aes(x = x, next_x = next_x, node = node, next_node = next_node, 
             fill = factor(node), label = node)) +
  geom_alluvial(flow.alpha = .6, node.color = "gray20") +
  geom_alluvial_label(size = 3, color = "white", fill = "gray50") +
  scale_fill_viridis_d() + labs(x = NULL) + 
  theme_alluvial(base_size = 18) + theme(legend.position = "none")

Sankey diagramm 🏠

Sankey diagramm 🏠

Код

# install.packages("devtools")
# devtools::install_github("davidsjoberg/ggsankey")
library(ggsankey)

recipes %>% select(-ingredients) %>% distinct() %>% 
  make_long(cuisine, course, diet) %>% 
  ggplot(aes(x = x, next_x = next_x, node = node, next_node = next_node, 
             fill = factor(node), label = node)) +
  geom_sankey(flow.alpha = .6, node.color = "gray20") +
  geom_sankey_label(size = 3, color = "white", fill = "gray50") +
  scale_fill_viridis_d() + labs(x = NULL) + 
  theme_sankey(base_size = 18) + theme(legend.position = "none")

Визуализация графов 🏠

# install.packages("igraph")
library(igraph)

recipes_links
# A tibble: 50 × 4
   recipe         ingredients     cuisine weight
   <chr>          <chr>           <chr>    <int>
 1 Regular Crepes Flour           French       3
 2 Regular Crepes Sugar           French       2
 3 Regular Crepes Baking Powder   French       3
 4 Regular Crepes Salt            French       1
 5 Regular Crepes Milk            French       2
 6 Regular Crepes Butter          French       3
 7 Regular Crepes Vanilla Extract French       1
 8 Regular Crepes Egg             French       3
 9 Croissants     Active Yeast    French       3
10 Croissants     Water           French       1
# ℹ 40 more rows

Визуализация графов 🏠

g <- graph_from_data_frame(d = recipes_links, directed = FALSE)
plot(g)

Визуализация графов 🏠

recipes_nodes
# A tibble: 34 × 3
   name            type        cuisine
   <chr>           <chr>       <chr>  
 1 Regular Crepes  recipe      French 
 2 Flour           ingredients French 
 3 Sugar           ingredients French 
 4 Baking Powder   ingredients French 
 5 Salt            ingredients French 
 6 Milk            ingredients French 
 7 Butter          ingredients French 
 8 Vanilla Extract ingredients French 
 9 Egg             ingredients French 
10 Croissants      recipe      French 
# ℹ 24 more rows

Визуализация графов 🏠

g <- graph_from_data_frame(d = recipes_links, vertices = recipes_nodes, directed = FALSE)
V(g)$shape <- ifelse(V(g)$type == "recipe", "square", "circle")
V(g)$color <- ifelse(V(g)$cuisine == "French", "#7cb518", "#fb6107")

plot(g, edge.width = recipes_links$weight, vertex.frame.color = "black",
     vertex.label.color = "black", vertex.label.family="Helvetica")

Ridgeline plot

ggridges

# install.packages("ggridges")
library(ggridges)

ggplot(penguins, aes(x = flipper_length_mm, y = species, fill = species)) + 
  geom_density_ridges(alpha = 0.8) +                                        
  scale_fill_manual(values = c("#1f985e", "#ffc700", "#147d4b")) +          
  labs(x = "Flipper length (mm)", y = "") + theme_bw() +                     
  theme(legend.position = "none",                                           
        axis.text = element_text(size = 12, color = "black"))               

Lollipop plot

  • аналог столбчатой диаграммы
# install.packages("ggalt")
library(ggalt)

ggplot(penguins, aes(x = 1:nrow(penguins), y = body_mass_g, color = species)) + 
  geom_lollipop() +                                                             
  labs(x = "Penguins", y = "Body mass (g)", color = "") + theme_classic() +      
  theme(legend.position = "top",                                                
        legend.key = element_rect(fill = "white", colour = "black"),            
        legend.text = element_text(size = 12),                                  
        axis.text = element_text(size = 12, color = "black"))                   

Lollipop plot

Raincloud plot

  • 3 варианта визуализации распределения на одном графике
ggplot(penguins, aes(x = species, y = body_mass_g, color = species)) +    
  ggdist::stat_halfeye(aes(fill = species),                               
    adjust = 0.5, width = 0.6, .width = 0,                                
    justification = -0.2, point_colour = NA) +                            
  geom_boxplot(width = 0.2, outlier.shape = NA) +                         
  gghalves::geom_half_point(side = "l", range_scale = 0.5, alpha = 0.3) + 
  labs(x = "", y = "Body mass (g)") + theme_classic() +                   
  theme(legend.position = "none")                                         

Raincloud plot

Интерактивная графика

# install.packages("plotly")
library(plotly)

penguins_plot <- penguins %>% 
  ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
  geom_point(size = 2) + theme_bw() 

ggplotly(penguins_plot)

Интерактивная графика

Интерактивная графика

penguins_plot <- penguins %>% 
  ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
  geom_point(size = 2, aes(text = sprintf("Species: %s \n Sex: %s", species, sex))) + 
  theme_bw() 

ggplotly(penguins_plot, tooltip = c("text"))

Интерактивная графика

Интерактивная графика 🏠

Некоторые пакеты для графики предоставляют возможность создавать интерактивные варианты визуализаций:

Графики для публикации

  • один график - одна мысль
  • сохраняйте графики в нужном размере и разрешении
  • настраивайте размеры текстовых элементов в зависимости от размеров графика
  • используйте более яркие цвета, так как при печати или демонстрации слайдов блеклые цвета будут не видны или неразличимы
    • текстовые элементы по осям X и Y в ggplot2 графиках по умолчанию серого цвета - делайте их черными, чтобы при печати они были более различимы
    • серые направляющие на графике тоже могут быть плохо видны
    • по возможности используйте цветовые палитры, подходящие для людей с ограниченными возможностями (color blind friendly)
  • в случае использования графиков, например, в постере с цветным фоном задавайте графикам прозрачный фон:
    • theme(panel.background = element_rect(fill = "transparent"), plot.background = element_rect(fill = "transparent", color = NA), ...) и ggsave("my_plot.png", bg = "transparent")

Таблицы

Таблица

Источник: gt

Сводная таблица

Источник: gtsummary

Таблица…

Источник: Table Gallery

Автор: Abdoul ISSA BIDA

Таблица gt

# install.packages("gt")
library(gt)

starwars10 %>% gt()
name height mass hair_color skin_color eye_color birth_year sex gender homeworld species
Obi-Wan Kenobi 182 77 auburn, white fair blue-gray 57.0 male masculine Stewjon Human
Han Solo 180 80 brown fair brown 29.0 male masculine Corellia Human
C-3PO 167 75 NA gold yellow 112.0 none masculine Tatooine Droid
Palpatine 170 75 grey pale yellow 82.0 male masculine Naboo Human
Chewbacca 228 112 brown unknown blue 200.0 male masculine Kashyyyk Wookiee
Darth Vader 202 136 none white yellow 41.9 male masculine Tatooine Human
R2-D2 96 32 NA white, blue red 33.0 none masculine Naboo Droid
Yoda 66 17 white green brown 896.0 male masculine NA Yoda's species
Leia Organa 150 49 brown light brown 19.0 female feminine Alderaan Human
Luke Skywalker 172 77 blond fair blue 19.0 male masculine Tatooine Human

Структура таблицы

Шапка и подвал таблицы

Дополнительные элементы добавляются в таблицу с помощью конвейера.

starwars_gt <- starwars10 %>% gt() %>% 
  # Заголовок и подзаголовок
  tab_header(
    title = "Star Wars characters",
    subtitle = "Top 10 most popular characters") %>% 
  # Примечание к источнику
  tab_source_note(
    source_note = "Source: R package {dplyr}. The original data is from SWAPI, the Star Wars API.") %>% 
  # Сноски
  tab_footnote(
    footnote = "My favourite characters.",
    locations = cells_body(columns = name, rows = c(3 ,7)))

Шапка и подвал таблицы

starwars_gt
Star Wars characters
Top 10 most popular characters
name height mass hair_color skin_color eye_color birth_year sex gender homeworld species
Obi-Wan Kenobi 182 77 auburn, white fair blue-gray 57.0 male masculine Stewjon Human
Han Solo 180 80 brown fair brown 29.0 male masculine Corellia Human
C-3PO1 167 75 NA gold yellow 112.0 none masculine Tatooine Droid
Palpatine 170 75 grey pale yellow 82.0 male masculine Naboo Human
Chewbacca 228 112 brown unknown blue 200.0 male masculine Kashyyyk Wookiee
Darth Vader 202 136 none white yellow 41.9 male masculine Tatooine Human
R2-D21 96 32 NA white, blue red 33.0 none masculine Naboo Droid
Yoda 66 17 white green brown 896.0 male masculine NA Yoda's species
Leia Organa 150 49 brown light brown 19.0 female feminine Alderaan Human
Luke Skywalker 172 77 blond fair blue 19.0 male masculine Tatooine Human
Source: R package {dplyr}. The original data is from SWAPI, the Star Wars API.
1 My favourite characters.

Сочетание с markdown

starwars_gt <- starwars10 %>% gt() %>% 
  # Заголовок и подзаголовок
  tab_header(
    title = md("**Star Wars characters**"),
    subtitle = "Top 10 most popular characters") %>% 
  # Примечание к источнику
  tab_source_note(
    source_note = md("Source: R package ***{dplyr}***. The original data is from [SWAPI](https://swapi.dev), the Star Wars API.")) %>% 
  # Сноски
  tab_footnote(
    footnote = "My favourite characters.",
    locations = cells_body(columns = name, rows = c(3 ,7)))

Сочетание с markdown

starwars_gt
Star Wars characters
Top 10 most popular characters
name height mass hair_color skin_color eye_color birth_year sex gender homeworld species
Obi-Wan Kenobi 182 77 auburn, white fair blue-gray 57.0 male masculine Stewjon Human
Han Solo 180 80 brown fair brown 29.0 male masculine Corellia Human
C-3PO1 167 75 NA gold yellow 112.0 none masculine Tatooine Droid
Palpatine 170 75 grey pale yellow 82.0 male masculine Naboo Human
Chewbacca 228 112 brown unknown blue 200.0 male masculine Kashyyyk Wookiee
Darth Vader 202 136 none white yellow 41.9 male masculine Tatooine Human
R2-D21 96 32 NA white, blue red 33.0 none masculine Naboo Droid
Yoda 66 17 white green brown 896.0 male masculine NA Yoda's species
Leia Organa 150 49 brown light brown 19.0 female feminine Alderaan Human
Luke Skywalker 172 77 blond fair blue 19.0 male masculine Tatooine Human
Source: R package {dplyr}. The original data is from SWAPI, the Star Wars API.
1 My favourite characters.

Боковик

starwars_gt <- starwars10 %>% 
  gt(rowname_col = "name") %>% 
  # Название боковика
  tab_stubhead(label = "Character name") %>% 
  tab_header(
    title = md("**Star Wars characters**"),
    subtitle = "Top 10 most popular characters") %>% 
  tab_source_note(
    source_note = md("Source: R package ***{dplyr}***. The original data is from [SWAPI](https://swapi.dev), the Star Wars API.")) %>% 
  tab_footnote(
    footnote = "My favourite characters.",
    locations = cells_stub(rows = c(3 ,7)))

Боковик

starwars_gt
Star Wars characters
Top 10 most popular characters
Character name height mass hair_color skin_color eye_color birth_year sex gender homeworld species
Obi-Wan Kenobi 182 77 auburn, white fair blue-gray 57.0 male masculine Stewjon Human
Han Solo 180 80 brown fair brown 29.0 male masculine Corellia Human
C-3PO1 167 75 NA gold yellow 112.0 none masculine Tatooine Droid
Palpatine 170 75 grey pale yellow 82.0 male masculine Naboo Human
Chewbacca 228 112 brown unknown blue 200.0 male masculine Kashyyyk Wookiee
Darth Vader 202 136 none white yellow 41.9 male masculine Tatooine Human
R2-D21 96 32 NA white, blue red 33.0 none masculine Naboo Droid
Yoda 66 17 white green brown 896.0 male masculine NA Yoda's species
Leia Organa 150 49 brown light brown 19.0 female feminine Alderaan Human
Luke Skywalker 172 77 blond fair blue 19.0 male masculine Tatooine Human
Source: R package {dplyr}. The original data is from SWAPI, the Star Wars API.
1 My favourite characters.

Группы строк

“Вручную” сгруппировать строки можно с помощью функции tab_row_group().

starwars_gt <- starwars10 %>% 
  gt(
    rowname_col = "name",
    groupname_col = "sex") %>% 
  row_group_order(groups = c("female", "male", "none")) %>% 
  tab_stubhead(label = "Character name") %>% 
  tab_header(
    title = md("**Star Wars characters**"),
    subtitle = "Top 10 most popular characters") %>% 
  tab_source_note(
    source_note = md("Source: R package ***{dplyr}***. The original data is from [SWAPI](https://swapi.dev), the Star Wars API.")) %>% 
  tab_footnote(
    footnote = "My favourite characters.",
    locations = cells_stub(rows = c(3 ,7))) %>% 
  tab_options(
    row_group.background.color = "#ece484",
    row_group.font.weight = "bold")

starwars_gt
Star Wars characters
Top 10 most popular characters
Character name height mass hair_color skin_color eye_color birth_year gender homeworld species
female
Leia Organa 150 49 brown light brown 19.0 feminine Alderaan Human
male
Obi-Wan Kenobi 182 77 auburn, white fair blue-gray 57.0 masculine Stewjon Human
Han Solo 180 80 brown fair brown 29.0 masculine Corellia Human
Palpatine 170 75 grey pale yellow 82.0 masculine Naboo Human
Chewbacca 228 112 brown unknown blue 200.0 masculine Kashyyyk Wookiee
Darth Vader 202 136 none white yellow 41.9 masculine Tatooine Human
Yoda 66 17 white green brown 896.0 masculine NA Yoda's species
Luke Skywalker 172 77 blond fair blue 19.0 masculine Tatooine Human
none
C-3PO1 167 75 NA gold yellow 112.0 masculine Tatooine Droid
R2-D21 96 32 NA white, blue red 33.0 masculine Naboo Droid
Source: R package {dplyr}. The original data is from SWAPI, the Star Wars API.
1 My favourite characters.

Группы столбцов

starwars_gt <- starwars_gt %>% 
  # Группа столбцов
  tab_spanner(
    label = "Character appearance",
    columns = c(height, mass,   hair_color, skin_color, eye_color))

starwars_gt
Star Wars characters
Top 10 most popular characters
Character name Character appearance birth_year gender homeworld species
height mass hair_color skin_color eye_color
female
Leia Organa 150 49 brown light brown 19.0 feminine Alderaan Human
male
Obi-Wan Kenobi 182 77 auburn, white fair blue-gray 57.0 masculine Stewjon Human
Han Solo 180 80 brown fair brown 29.0 masculine Corellia Human
Palpatine 170 75 grey pale yellow 82.0 masculine Naboo Human
Chewbacca 228 112 brown unknown blue 200.0 masculine Kashyyyk Wookiee
Darth Vader 202 136 none white yellow 41.9 masculine Tatooine Human
Yoda 66 17 white green brown 896.0 masculine NA Yoda's species
Luke Skywalker 172 77 blond fair blue 19.0 masculine Tatooine Human
none
C-3PO1 167 75 NA gold yellow 112.0 masculine Tatooine Droid
R2-D21 96 32 NA white, blue red 33.0 masculine Naboo Droid
Source: R package {dplyr}. The original data is from SWAPI, the Star Wars API.
1 My favourite characters.

Сохранение таблицы

# install.packages("webshot2")

gtsave(starwars_gt, "starwars.html")
gtsave(starwars_gt, "starwars.png")

Дополнительные пакеты

gtExtras

Вспомогательные функции для создания красивых таблиц с помощью gt.

gtsummary

Добавление к gt-таблицам описательных статистик и создания сводных таблиц.

Конец!