Табличный способ является одним из основных способов структурирования и представления данных. В отличие от графиков, таблицы, как правило, не дают быстрого визуального представления о данных. Тем не менее, таблицы используются для того, чтобы показать точные значения данных. Правильно созданная таблица позволяет построить описательную статистику, обобщить модели регрессии или получить статистические данные отчета.
Мы рассмотрим представление данных средствами языка программирования R в виде интерактивных таблиц. Одним из самых простых способов для формирования интерактивных таблиц в R является библиотека DT, которая позволяет делать удобную сортировку и фильтрацию данных, а также предоставляет массу других дополнительных возможностей. Таблицы, которые мы рассмотрим здесь, построены в достаточно насыщенной возможностями библиотекеreactable, основанной на JavaScript-библиотеке React Table и разработанной с помощью reactR.
В качестве основного примера рассмотрим данные по техногенным и бытовым пожарам1, нормированные на численность населения в соответствующем субъекте Российской Федерации2.
Количество пожаров приведенное на 10 000 человек населения
Субъект РФ
ФО
2017
2018
2019
2020
Сумма
Еврейская автономная область
ДФО
95
109
137
91
431
Приморский край
ДФО
74
79
98
51
301
Хабаровский край
ДФО
76
76
89
59
299
Забайкальский край
ДФО
68
62
95
65
289
Магаданская область
ДФО
75
67
65
58
266
Амурская область
ДФО
64
77
68
51
261
Сахалинская область
ДФО
61
55
65
41
222
Республика Бурятия
ДФО
57
50
50
38
195
Камчатский край
ДФО
51
43
40
41
174
Чукотский автономный округ
ДФО
38
39
36
28
140
Республика Саха (Якутия)
ДФО
39
39
27
25
131
Оренбургская область
ПФО
41
55
44
41
182
Ульяновская область
ПФО
40
53
47
41
182
Саратовская область
ПФО
38
45
38
43
165
Республика Мордовия
ПФО
28
45
52
36
161
Самарская область
ПФО
24
38
36
31
128
Республика Башкортостан
ПФО
21
26
29
27
102
Пензенская область
ПФО
22
27
28
23
101
Кировская область
ПФО
23
26
22
17
88
Республика Марий Эл
ПФО
19
24
26
17
86
Пермский край
ПФО
18
20
16
15
68
Удмуртская Республика
ПФО
18
18
16
14
66
Нижегородская область
ПФО
13
19
17
16
65
Республика Татарстан
ПФО
14
16
16
14
59
Чувашская Республика - Чувашия
ПФО
14
19
14
13
59
Диапазон: с 1 по 25 из 85 регионов
значений
Отметим, что таблица выше не является официальным статистическим отчетом и служит исключительно для демонстрации работы библиотеки. Основные показатели, характеризующие состояние пожарной безопасности в Российской Федерации, ежегодно публикуются ФГБУ ВНИИПО МЧС РОССИИ в статистических сборниках ПОЖАРЫ И ПОЖАРНАЯ БЕЗОПАСНОСТЬ.
Некоторые особенности и возможности интерактивных таблиц
Отметим преимущества интерактивных таблиц.
Возможность интерактивной сортировки значений по столбцам (при необходимости можно указать исходное направление сортировки).
Живой поиск, позволяющий выделять только строки с нужными значениями и делать автоматический пересчет итоговых суммарных значений.
Регулировка количества строк на странице и диапазона значений.
Группировка и агрегирование строк с автоматическим выделением границ группы.
Возможность условного форматирования: выделение шрифтом и цветом значений на основе условных критериев, построения тепловых карт и т.д.
Использование JavaScript для улучшения стилизации и внедрение HTML-виджетов в таблицы.
Использование CSS-стилей.
Богатые возможности для локализации.
Интегрирование с Shiny (интерактивной средой для создания веб-приложений и дэшбордов) и Leaflet (библиотекой предназначенной для отображения интерактивных карт на веб-сайтах).
Код для построения рассмотренной выше таблицы по пожарам довольно большой, поэтому вместо полного листинга приведем основные идеи и принципы создания интерактивных таблиц в reactable на основе небольших примеров описанных на странице библиотеки.
Пусть модельные данные представляют собой упрощенную таблицу, содержащую название региона, федерального округа, данные за определенный период и столбец с некоторыми суммарными значениями.
fires_reactable
# A tibble: 85 × 7
regions FO `2017` `2018` `2019` `2020` total
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Еврейская автономная область ДФО 95 109 137 91 431
2 Приморский край ДФО 74 79 98 51 301
3 Хабаровский край ДФО 76 76 89 59 299
4 Забайкальский край ДФО 68 62 95 65 289
5 Псковская область СЗФО 68 63 92 66 289
6 Магаданская область ДФО 75 67 65 58 266
7 Амурская область ДФО 64 77 68 51 261
8 Республика Калмыкия ЮФО 58 66 67 65 255
9 Орловская область ЦФО 50 50 58 67 225
10 Алтайский край СФО 52 54 62 56 224
# ℹ 75 more rows
Для отображения интерактивной таблицы служит команда reactable(). Столбцы такой таблицы можно сортировать нажатием (или кликом) на них.
reactable(fires_reactable)
regions
FO
2017
2018
2019
2020
total
Алтайский край
СФО
52
54
62
56
224
Амурская область
ДФО
64
77
68
51
261
Архангельская область
СЗФО
11
12
12
11
46
Астраханская область
ЮФО
52
52
48
54
205
Белгородская область
ЦФО
11
12
18
17
59
Брянская область
ЦФО
51
44
47
39
182
Владимирская область
ЦФО
25
35
32
25
118
Волгоградская область
ЮФО
50
45
37
47
179
Вологодская область
СЗФО
25
25
19
16
86
Воронежская область
ЦФО
30
34
32
45
141
Диапазон: с 1 по 10 из 85 регионов
...
Локализация таблиц
Одна из ключевых возможностей отличающих reacable это, несомненно, возможность настройки языковых опций таблицы.3
# русификация reactable таблицoptions(reactable.language =reactableLang(pageSizeOptions ="показано {rows} значений",pageInfo ="Диапазон: с {rowStart} по {rowEnd} из {rows} регионов",pagePrevious ="назад",pageNext ="вперед",searchPlaceholder ="Поиск...",noData ="Значения не найдены"))
Пример локализации
reactableLang(sortLabel ="Сортировать {name}",filterPlaceholder ="",filterLabel ="Фильтровать {name}",searchPlaceholder ="Найти",searchLabel ="Найти",noData ="Строки не найдены",pageNext ="Далее",pagePrevious ="Назад",pageNumbers ="{page} из {pages}",pageInfo ="{rowStart}\u2013{rowEnd} из {rows} строк",pageSizeOptions ="Показать {rows}",pageNextLabel ="Следующая страница",pagePreviousLabel ="Предыдущая страница",pageNumberLabel ="Страница {page}",pageJumpLabel ="Перейти на страницу",pageSizeOptionsLabel ="Строк на странице",groupExpandLabel ="Группировка",detailsExpandLabel ="Детальный вид",selectAllRowsLabel ="Выбрать все строки",selectAllSubRowsLabel ="Выбрать все строки в группе",selectRowLabel ="Выбрать строку",defaultGroupHeader =NULL,detailsCollapseLabel =NULL,deselectAllRowsLabel =NULL,deselectAllSubRowsLabel =NULL,deselectRowLabel =NULL)
Глобальные настройки таблицы
Таблицы в reactable имеют огромное количество разнообразных настроек, причем для более глубокой настройки используется JavaScript. Приведем ниже некоторые возможности на примере.
Код
year_cols <-c("2017", "2018", "2019", "2020")reactable(fires_reactable,compact =TRUE,columns =list(regions =colDef(minWidth =280, name ="Субъект РФ"),FO =colDef(minWidth =70, name ="ФО"),total =colDef(name ="Сумма") ),# группировка и название объединенных столбцовcolumnGroups =list(colGroup(name ="Количество пожаров приведенное на 10 000 человек населения", columns = year_cols) ),# строка поискаsearchable =TRUE,# исходная глобальная сортировка по умолчаниюdefaultSortOrder ="desc",# возможность изменять количество строк на страницеshowPageSizeOptions =TRUE,# подсветка при наведении на строкуhighlight =TRUE,# отстутствие границы между строкамиborderless =TRUE,# на всю ширину / фиксированная ширинаfullWidth =TRUE,# столбцы исходной сортировки и направление сортировки столбцовdefaultSorted =list(FO ="asc"),# исходное количество строк на страницеdefaultPageSize =12,# стилизация заголовков столбцовtheme =reactableTheme(headerStyle =list("&:hover[aria-sort]"=list(background ="hsl(0, 0%, 96%)"),"&[aria-sort='ascending'], &[aria-sort='descending']"=list(background ="hsl(0, 0%, 96%)"),borderColor ="#555" ) ),# стилизация: разграничивание между группами при сортировке по ФОrowStyle =JS(" function(rowInfo, state) { // игнорирование строк заполнения if (!rowInfo) return // горизонтальные разделители между группами var firstSorted = state.sorted[0] if (firstSorted && firstSorted.id === 'FO') { var nextRow = state.pageRows[rowInfo.viewIndex + 1] if (nextRow && rowInfo.row['FO'] !== nextRow['FO']) { // добавление прямоугольной тени, // чтобы добавить границу 2 пикселя return { boxShadow: 'inset 0 -2px 0 rgba(0, 0, 0, 0.1)' } } } } "),# глобальный стиль: шрифт для подстрочной суммыdefaultColDef =colDef(footerStyle =list(fontWeight ="bold"), # разделитель для тысяч пробеломformat =colFormat(locales ="ru-RU", separators =TRUE)) )
Количество пожаров приведенное на 10 000 человек населения
Субъект РФ
ФО
2017
2018
2019
2020
Сумма
Еврейская автономная область
ДФО
95
109
137
91
431
Приморский край
ДФО
74
79
98
51
301
Хабаровский край
ДФО
76
76
89
59
299
Забайкальский край
ДФО
68
62
95
65
289
Магаданская область
ДФО
75
67
65
58
266
Амурская область
ДФО
64
77
68
51
261
Сахалинская область
ДФО
61
55
65
41
222
Республика Бурятия
ДФО
57
50
50
38
195
Камчатский край
ДФО
51
43
40
41
174
Чукотский автономный округ
ДФО
38
39
36
28
140
Республика Саха (Якутия)
ДФО
39
39
27
25
131
Оренбургская область
ПФО
41
55
44
41
182
Диапазон: с 1 по 12 из 85 регионов
показано значений
...
Настройка столбцов в таблицах
Для настройки столбцов в reactable-таблицах (например, изменения имени, настройки поиска по столбцу) используется функция colDef(), подробно описанная на соответствующей странице. Приведем простой пример настройки столбцов на базе известного набора данных palmerpenguins.
Возможности colDef() очень богатые: можно менять выравнивание конкретного столбца, его ширину, указав значение maxWidth, изменить форматирование столбца, добавив CSS-стиль и т.д.
Тепловые карты
Известно, что цвет воспринимается гораздо эффективнее, чем численные значения, поэтому иногда имеет смысл представлять данные в виде так называемых тепловых карт. Для создания тепловой карты необходима сначала определить стиль столбцов.
Для компактного представления больших таблиц имеет смысл делать группировку показателей по выбранной переменной с раскрывающимся списком. В примере ниже группировка сделана по федеральным округам. Кроме того, в такого рода таблице можно показать агрегированные значения, такие как максимум по столбцу, минимум, среднее значение, медиану, количество элементов, уникальные значения и т.д.
Библиотека reactable путем удачного сочетания с JavaScript позволяет делать таблицы с динамической визуализацией в виде итоговой сноски, например, при наборе фильтрующего значения может происходить автоматический пересчет суммы. Скажем, если в поле поиска таблицы ниже ввести область, то останутся субъекты РФ, соответствующие областям.
Код
set.seed(123)reactable(compact =TRUE, fires_reactable |> dplyr::select(-FO) |>slice_sample(n =20),searchable =TRUE,highlight =TRUE,borderless =TRUE,defaultPageSize =5,theme =reactableTheme(searchInputStyle =list(width ="100%")),columns =list(regions =colDef(name ="Субъект РФ",minWidth =200,footer ="Всего:"),total =colDef(name ="Сумма",# разделитель для тысяч пробеломformat =colFormat(locales ="ru-RU", separators =TRUE),# динамический пересчет суммы при поискеfooter =JS("function(colInfo) {var total = 0 colInfo.data.forEach(function(row) { total += row[colInfo.column.id] }) return total.toLocaleString('ru-RU') }") ) ),# глобальный стиль: шрифт для подстрочной суммыdefaultColDef =colDef(footerStyle =list(fontWeight ="bold"),# разделитель для тысяч пробеломformat =colFormat(locales ="ru-RU", separators =TRUE) ))
Субъект РФ
2017
2018
2019
2020
Сумма
Смоленская область
31
44
49
40
164
Карачаево-Черкесская Республика
12
7
17
17
54
Томская область
32
29
32
25
118
Тульская область
46
56
51
47
201
Кабардино-Балкарская Республика
21
18
18
21
78
Диапазон: с 1 по 5 из 20 регионов
Условное форматирование
Зачастую в таблице необходимо отобразить динамику изменения показателя. Для этого удобно применять условное форматирование, например, выделив цветом разности между конечным и исходным значениями и т.д.
Для дополнительных возможностей оптимизации и улучшения стиля и форматирования таблиц, созданных с помощью reactable, можно воспользоваться библиотекой reactablefmtr. В дополнении к огромным возможностям reactable, мы получаем множество средств условного форматирования, интерактивные спарклайны, пользовательские темы таблиц, встраивание изображений в таблицы, использование crosstalk и shiny, темы, и многое другое. Больше примеров можно посмотреть на сайте библиотекиreactablefmtr.
# цвет для sparkline-графиковfires_table_reactable <- fires_table_reactable |>mutate(cols =case_when( year =="2017"~"#1b9e77", year =="2018"~"#d95f02", year =="2019"~"#7570b3", year =="2020"~"#e7298a",.default ="grey" ) )reactable( fires_table_reactable,defaultPageSize =4,columns =list(year =colDef(maxWidth =100,name ="Год"),cols =colDef(show =FALSE),fire_num =colDef(name ="Приведенное количество пожаров",cell =react_sparkbar( fires_table_reactable,height =90,fill_color_ref ="cols",tooltip_type =2,bandline ="innerquartiles",statline ="mean" ) ) ))
Год
Приведенное количество пожаров
2017
2018
2019
2020
Заключение
В статье был сделан краткий обзор некоторых инструментов по созданию таблиц в библиотеке reactable:
формирование интерактивной таблицы;
возможности глобальных настроек и настроек столбцов;
дополнительные возможности для создания тепловых карт;
группировка и аггрегирование ячеек;
некоторые JavaScript опции;
стилизация таблиц.
Всесторонне описать все возможности создания интерактивных таблиц в reactable в рамках одной статьи очень сложно. Например, мы не затронули CSS-стили, изображения, HTML-виджеты, внедрение reactable в Shiny и Leaflet и многое другое. Как было сказано, страница библиотеки содержит большое количество материала с примерами и замечательными демонстрациями, включая полный код и описание.
Подводя итог, отметим что базовые принципы построения эффективных таблиц, которые можно взять за основу для презентации своих данных, описаны во многих источниках, например, в статье Ten Guidelines for Better Tables. Основные тезисы этой статьи можно посмотреть в твите (на английском языке) ниже.
Здесь рассмотрены пожары, учет которых ведется на основании Приказа МЧС России от 24.12.2018 №625 «О формировании электронных баз данных учета пожаров и их последствий» (утратил силу).↩︎
Нормирование по отношению к численности населения производилось на основе статистических данных statdata.ru на 1 января 2021 года. Оценку численности постоянного населения РФ можно также посмотреть на странице ИНИД: Демографическая ситуация по субъектам РФ.↩︎