tidyverseБиблиотека tidyverse — библиотека для удобной работы с данными, которая активно используется в аналитике. С ее помощью можно более быстро получать описание датафрейма, сохранять полученные результаты, группировать наблюдения по определенному признаку, а также строить красивые графики. Научиться работать с это библиотекой несложно, нужно только понять общую логику, познакомиться с особыми операторами и функциями.
Библиотека tidyverse — огромная библиотека для обработки и визуализации данных, которая состоит сразу из нескольких более маленьких библиотек. Откроем главную страницу tidyverse и зайдем в раздел Packages. Какие составные части есть у tidyverse?
Библиотеки dplyr, tidyr и tibble, которые позволяют выполнять манипуляции со строками и столбцами датафрейма, группировать и агрегировать данные, изменять их структуру.
Библиотека ggplot2 — библиотека для визуализации данных разных типов.
Библиотека readr для чтения файлов в табличном виде (csv, tsv и так далее).
Библиотека purr для выполнения более эффективных векторизованных операций.
Библиотека stringr для работы со строками: поиск по строкам и их редактирование, в том числе с использованием регулярных выражений.
Библиотека forcats для работы с категориальными или качественными, то есть неколичественными данными. Включает возможности изменения уровней факторных показателей и их группировку.
Итак, мы познакомились с основными частями библиотеки tidyverse, теперь самое время ее установить. Воспользуемся функцией install.packages():
install.packages("tidyverse")
Теперь обратимся к библиотеке, чтобы R понимал, откуда брать функции для работы:
library(tidyverse)
Все готово к работе. Загрузим данные из файла CPI2019.csv (его можно найти в материалах к уроку). Этот файл содержит значения индекса восприятия коррупции (Corruption Perception Index) за 2019 год. Чем больше значение индекса, тем свободнее страна от коррупции. Загрузим csv-файл в R (обратите внимание, что разделителем столбцов является точка с запятой):
#setwd("/Users/allat/Desktop")
cpi <- read.csv("CPI2019.csv", sep = ";")
Посмотрим на содержимое файла:
View(cpi)
Пояснения по столбцам:
country: страна;iso3: код страны;region: регион;cpi_score: значения индекса;cpi_rank: ранг страны (номер в наборе значений индекса, упорядоченных по убыванию, чем меньше ранг, тем более свободна страна от коррупции);n_sources: число источников, на основе которых был посчитан индекс.В библиотеке tidyverse есть особый оператор %>% (pipe operator), который позволяет выполнять операции пошагово, друг за другом. Смысл этого оператора такой: возьми, то, что слева от %>% и передай это на вход функции, стоящей справа от %>%. Посмотрим на простом примере:
cpi %>% View
Взять датафрейм cpi и подать ее на вход функции View. Как можно заметить, во View уже нет ни скобок, ни названия датафрейма, потому что они и не нужны – R и так знает, с чем ему работать. Рассмотрим другой пример. Выберем первые несколько строк в датафрейме cpi и выведем их в отдельном окне в режиме View:
cpi %>% head %>% View
Благодяря оператору %>%, R понимает, что к датафрейму cpi нужно применить функцию head(), а к полученному в head() результату — функцию View(). Таким образом, в одной строке мы «наслаиваем» функции друг на друга, что выглядит компактно и удобно.
tidyverse: часть 1Для выбора столбцов по названию используется функция select(). Например, выведем на экран столбец country:
cpi %>% select(country) %>% head
##       country
## 1     Denmark
## 2 New Zealand
## 3     Finland
## 4   Singapore
## 5      Sweden
## 6 Switzerland
Если нам нужно выбрать несколько столбцов, их названия необходимо перечислить через запятую в select(), при этом оформлять их в вектор совсем необязательно. Выберем столбцы country и cpi_score и сохраним в маленький датафрейм small1:
small1 <- cpi %>% select(country, cpi_score)
View(small1)
Если столбцы, которые мы хотим выбрать, стоят друг за другом, мы можем воспользоваться последовательностью из названий:
# с iso3 по cpi_score
small2 <- cpi %>% select(iso3:cpi_score)
View(small2)
Если нам нужно выбрать все столбцы, кроме какого-то одного, перед его названием можно поставить минус:
small3 <- cpi %>% select(-iso3)
View(small3)
Если столбцов, которые мы хотим исключить, несколько, их названия нужно оформить в виде вектора, и перед всем вектором поставить минус:
small4 <- cpi %>% select(-c(iso3, region))
View(small4)
Если названия у столбцов слишком длинные, и мы не хотим их писать, а хотим выбирать столбцы по номеру, функцию select() также можно использовать:
cpi %>% select(1, 3) %>% head
##       country region
## 1     Denmark  WE/EU
## 2 New Zealand     AP
## 3     Finland  WE/EU
## 4   Singapore     AP
## 5      Sweden  WE/EU
## 6 Switzerland  WE/EU
Итак, мы разобрали различные варианты выбора столбцов. Перейдем к выбору строк. Строки мы чаще всего выбираем по условию или условиям. Для выбора строк по условиям или, другими словами, для построения фильтров, используется функция с говорящим названием filter(). Выберем строки, соответствующие странам со значением индекса больше 80:
cpi %>% filter(cpi_score > 80)
##       country iso3 region cpi_score cpi_rank n_sources
## 1     Denmark  DNK  WE/EU        87        1         8
## 2 New Zealand  NZL     AP        87        1         8
## 3     Finland  FIN  WE/EU        86        3         8
## 4   Singapore  SGP     AP        85        4         9
## 5      Sweden  SWE  WE/EU        85        4         8
## 6 Switzerland  CHE  WE/EU        85        4         7
## 7      Norway  NOR  WE/EU        84        7         7
## 8 Netherlands  NLD  WE/EU        82        8         8
Условие формулируется как обычно и указывается в скобках внутри filter(). Сформулируем более сложное условие — выберем страны со значением индекса более 80 и при этом находящиеся в Западной Европе:
cpi %>% filter(cpi_score > 80 & region == "WE/EU")
##       country iso3 region cpi_score cpi_rank n_sources
## 1     Denmark  DNK  WE/EU        87        1         8
## 2     Finland  FIN  WE/EU        86        3         8
## 3      Sweden  SWE  WE/EU        85        4         8
## 4 Switzerland  CHE  WE/EU        85        4         7
## 5      Norway  NOR  WE/EU        84        7         7
## 6 Netherlands  NLD  WE/EU        82        8         8
Два условия выполняются одновременно, поэтому их мы объединили с помощью оператора &. Однако в filter() эту запись можно упростить, эта функция автоматически объединяет условия, записанные через запятую:
# опускаем & и получаем то же самое
cpi %>% filter(cpi_score > 80, region == "WE/EU")
##       country iso3 region cpi_score cpi_rank n_sources
## 1     Denmark  DNK  WE/EU        87        1         8
## 2     Finland  FIN  WE/EU        86        3         8
## 3      Sweden  SWE  WE/EU        85        4         8
## 4 Switzerland  CHE  WE/EU        85        4         7
## 5      Norway  NOR  WE/EU        84        7         7
## 6 Netherlands  NLD  WE/EU        82        8         8
А вот для условия «или» нам понадобится оператор в явном виде. Выберем строки, соответствующие странам в регионе Западная Европа или Восточная Европа и Центральная Азия:
cpi %>% filter(region == "WE/EU" | region == "ECA")
Если бы регионов, нужных нам, было больше, было бы неудобно писать много похожих условий со знаком равенства. В таком случае можно было бы поступить проще — перечислить нужные регионы в виде вектора и сформулировать условие с помощью оператора %in% для проверки вхождения элементов в вектор:
cpi %>% filter(region %in% c("WE/EU", "ECA"))
Базовые случаи использования функций select() и filter() мы обсудили. Но это еще не все. Эти функции можно сочетать с другими полезными функциями tidyverse. Например, с функцией starts_with(), которая позволяет отобрать наблюдения или столбцы, которые начинаются определенным образом. Выберем столбцы, которые начинаются со слова cpi:
cpi %>% select(starts_with("cpi")) %>% head
##   cpi_score cpi_rank
## 1        87        1
## 2        87        1
## 3        86        3
## 4        85        4
## 5        85        4
## 6        85        4
В нашем датафрейме два таких столбца, cpi_score и cpi_rank, они и были выбраны. Если мы запросим help по функции starts_with() [запрашиваем], мы увидим, что по умолчанию аргумент ignore.case равен TRUE. Это означает, что R ищет совпадения вне зависимости от регистра, в независимости от того, большие буквы или маленькие. При желании этот аргумент можно изменить на FALSE.
Аналогичным образом можно воспользоваться функцией ends_with(). Найдем столбец, который заканчивается на score:
cpi %>% select(ends_with("score")) %>% head
##   cpi_score
## 1        87
## 2        87
## 3        86
## 4        85
## 5        85
## 6        85
Если нам не важно, где стоит слово или последовательность символов, в начале, в конце, в середине, мы можем воспользоваться функцией contains(), которая просто проверяет, содержит ли строка другую строку:
cpi %>% select(contains("n_")) %>% head
##   n_sources
## 1         8
## 2         8
## 3         8
## 4         9
## 5         8
## 6         7
При работе со строками пригодится функция str_detect(), которая также проверяет, входит ли указанная строка в другую строку. Например, выберем все страны, названия которых содержат слово Guinea:
cpi %>% filter(str_detect(country, "Guinea"))
##             country iso3 region cpi_score cpi_rank n_sources
## 1            Guinea  GIN    SSA        29      130         8
## 2  Papua New Guinea  PNG     AP        28      137         6
## 3     Guinea Bissau  GNB    SSA        18      168         6
## 4 Equatorial Guinea  GNQ    SSA        16      173         4
Если вы знакомы с регулярными выражениями, их тоже можно использовать в сочетании с функцией str_detect(). Про регулярные выражения в R и tidyverse в частности можно почитать в статьях по ссылкам в дополнительных материалах к уроку.
tidyverse: часть 2Для добавления нового столбца используется функция mutate(). Например, добавим в датафрейм cpi столбец cpi_perc, который будет содержать значения индекса в шкале от 0 до 1. Чтобы получить такой набор значений, нам нужно поделить столбец cpi_score на 100:
cpi %>% mutate(cpi_perc = cpi_score / 100)
Давайте проверим, добавился ли столбец:
cpi %>% colnames
## [1] "country"   "iso3"      "region"    "cpi_score" "cpi_rank"  "n_sources"
Новый столбец не добавился! Это ожидаемо, поскольку функция mutate() не изменяет исходный датафрейм, а возвращает обновленную копию датафрейма с добавленными столбцами. Чтобы сохранить изменения, нужно записать результат в переменную с тем же названием:
cpi <- cpi %>% mutate(cpi_perc = cpi_score / 100)
Теперь все на месте, функция mutate() добавляет столбец в конец датафрейма:
cpi %>% colnames
## [1] "country"   "iso3"      "region"    "cpi_score" "cpi_rank"  "n_sources"
## [7] "cpi_perc"
Используя mutate(), можно добавлять больше одного столбца за раз. Например, добавим столбец с индексом в шкале от 0 до 1 (у нас такой столбец уже создан, поэтому новый запишется поверх старого) и столбец eu со значениями 0 и 1, где 1 соответствует региону Западная Европа.
cpi <- cpi %>% mutate(cpi_perc = cpi_score / 100, 
                      eu = ifelse(region == "WE/EU", 1, 0))
Проверим:
cpi %>% head
##       country iso3 region cpi_score cpi_rank n_sources cpi_perc eu
## 1     Denmark  DNK  WE/EU        87        1         8     0.87  1
## 2 New Zealand  NZL     AP        87        1         8     0.87  0
## 3     Finland  FIN  WE/EU        86        3         8     0.86  1
## 4   Singapore  SGP     AP        85        4         9     0.85  0
## 5      Sweden  SWE  WE/EU        85        4         8     0.85  1
## 6 Switzerland  CHE  WE/EU        85        4         7     0.85  1
Все записалось.
Если мы хотим добавить новый столбец или новые столбцы в определенное место датафрейма, понадобится другая функция — add_column(). В нее можно добавить аргументы .before или .after, в которых указать, после какого столбца или перед каким столбцом добавить новый столбец или столбцы. Добавим столбец asia перед столбцом eu:
# регион AP или ECA
cpi <- cpi %>% add_column(asia = ifelse(cpi$region %in% c("AP", "ECA"), 1, 0), .before = "eu")
Обратите внимание на точку перед before или перед after, без точки R поймет нас неправильно, и будет считать, что это название нового столбца. Кроме того, название столбца в .before или .after вводится в кавычках, иначе R этот столбец не найдет. Вместо названия столбца можно просто указать номер столбца, уже без кавычек, как обычное целое число. Если опустить аргумент .before или .after, столбец будет записан в конец. И еще одно важное отличие add_column() от mutate(): эта функция не поддерживает выражения, связанные с уже существующими данными, поэтому внутри ifelse() нам пришлось вызывать столбец region через $ вместо того, чтобы просто написать region, как раньше.
Раз можно добавить новый столбец, можно добавить и новую строку. Для этого существует функция add_row(). Внутри этой функции нужно перечислить пары «название столбца-значение в этом столбце», причем перечислять можно в любом порядке. Добавим строку с данными по Люксембургу после третьей строки:
cpi <- cpi %>% add_row(country = "Luxembourg", iso3 = "LUX", region = "WE/EU", 
        cpi_score = 80, cpi_rank = 9, n_sources = NA, 
        eu = 1, asia = 0, .after = 3)
head(cpi)
##       country iso3 region cpi_score cpi_rank n_sources cpi_perc asia eu
## 1     Denmark  DNK  WE/EU        87        1         8     0.87    0  1
## 2 New Zealand  NZL     AP        87        1         8     0.87    1  0
## 3     Finland  FIN  WE/EU        86        3         8     0.86    0  1
## 4  Luxembourg  LUX  WE/EU        80        9        NA       NA    0  1
## 5   Singapore  SGP     AP        85        4         9     0.85    1  0
## 6      Sweden  SWE  WE/EU        85        4         8     0.85    0  1
На добавление новых столбцов и строк мы посмотрели. В завершение урока посмотрим на сортировку строк. Для сортировки используется функция arrange(), и сортировка по умолчанию производится по возрастанию. Упорядочим строки по показателю country, то есть по алфавиту по названию стран и сохраним изменения:
cpi <- cpi %>% arrange(country)
Для сортировки по убыванию нужно добавить функцию desc(), от английского descending order. Упорядочим строки по убыванию в соответствии с показателем cpi_rank:
cpi %>% arrange(desc(cpi_rank)) %>% View
Сортировку можно производить по нескольким показателям одновременно. Например, можно сделать так, чтобы сначала сортировка производилась по значению индекса, а затем, внутри сортировки по индексу, по названию страны:
cpi %>% arrange(cpi_score, country) %>% View
Для сортировки строк в tidyverse есть еще одна опция — функция top_n(). Эта функция позволяет выбрать первые несколько строк, которые являются топовыми (то есть с самыми большими значения) по некоторому показателю. Для примера выберем топ 10 стран по показателю cpi_score, по индексу восприятия коррупции, и сохраним их в датафрейм top10:
top10 <- cpi %>% top_n(10, cpi_score)
top10
##        country iso3 region cpi_score cpi_rank n_sources cpi_perc asia eu
## 1      Denmark  DNK  WE/EU        87        1         8     0.87    0  1
## 2      Finland  FIN  WE/EU        86        3         8     0.86    0  1
## 3      Germany  DEU  WE/EU        80        9         8     0.80    0  1
## 4   Luxembourg  LUX  WE/EU        80        9        NA       NA    0  1
## 5  Netherlands  NLD  WE/EU        82        8         8     0.82    0  1
## 6  New Zealand  NZL     AP        87        1         8     0.87    1  0
## 7       Norway  NOR  WE/EU        84        7         7     0.84    0  1
## 8    Singapore  SGP     AP        85        4         9     0.85    1  0
## 9       Sweden  SWE  WE/EU        85        4         8     0.85    0  1
## 10 Switzerland  CHE  WE/EU        85        4         7     0.85    0  1
Сгруппируем строки в датафрейме cpi по показателю region и выведем на экран число стран в каждом регионе. Для группировки воспользуемся функцией group_by(), для подсчета числа строк в каждой группе воспользуемся функцией tally():
cpi %>% group_by(region) %>% tally 
## # A tibble: 6 x 2
##   region     n
##   <chr>  <int>
## 1 AME       32
## 2 AP        31
## 3 ECA       19
## 4 MENA      18
## 5 SSA       49
## 6 WE/EU     31
Функция group_by() создает в R маленькие датафреймы, обработанные в tidyverse, так называемые tibbles, соответствующие каждой группы. А функция tally(), благодаря оператору %>% применяется к каждой группе, то есть к каждому объекту tibble.
Вывод сводной информации по группам можно получить с помощью функции summarise(). Внутри этой функции можно перечислять те характеристики по группам, которые нас интересуют, например, минимум, максимум, среднее или медиану. Для простоты начнем с числа наблюдений в каждой группе, но уже без tally(). Укажем внутри функции summarise() функцию n() для подчета числа строк и поместим эту информацию в столбец N:
cpi %>% group_by(region) %>% summarise(N = n()) 
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 6 x 2
##   region     N
##   <chr>  <int>
## 1 AME       32
## 2 AP        31
## 3 ECA       19
## 4 MENA      18
## 5 SSA       49
## 6 WE/EU     31
Получилось! Теперь посчитаем среднее значения индекса по каждой группе и его стандартное отклонение — меру разброса значений вокруг среднего:
cpi %>% group_by(region) %>% summarise(N = n(), 
                                       `Mean CPI` = mean(cpi_score),
                                       `Sd CPI` = sd(cpi_score)) 
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 6 x 4
##   region     N `Mean CPI` `Sd CPI`
##   <chr>  <int>      <dbl>    <dbl>
## 1 AME       32       43.4    16.4 
## 2 AP        31       44.9    20.0 
## 3 ECA       19       34.8     8.54
## 4 MENA      18       39      16.9 
## 5 SSA       49       32.2    12.6 
## 6 WE/EU     31       66.1    14.5
Обратите внимание: столбцы со сводной информацией можно называть как угодно, можно создавать названия с пробелами или названия на кириллице, только тогда названия нужно заключать в «обратные апострофы» — символы, которые, в частности, используются для создания ячеек с кодом в Rmd-файлах.
Теперь попробуем добавить среднее число источников, по которым был посчитан индекс, по каждой группе:
cpi %>% group_by(region) %>% summarise(N = n(), 
                                       `Mean CPI` = mean(cpi_score),
                                       `Sd CPI` = sd(cpi_score),
                                       `Mean N sources` = mean(n_sources))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 6 x 5
##   region     N `Mean CPI` `Sd CPI` `Mean N sources`
##   <chr>  <int>      <dbl>    <dbl>            <dbl>
## 1 AME       32       43.4    16.4              6.38
## 2 AP        31       44.9    20.0              6.94
## 3 ECA       19       34.8     8.54             7.11
## 4 MENA      18       39      16.9              6.61
## 5 SSA       49       32.2    12.6              6.94
## 6 WE/EU     31       66.1    14.5             NA
Среднее число источников посчиталось по каждой группе, кроме Европы. На месте европейского региона стоит NA. Почему? Потому что R не умеет расчитывать среднее числового вектора или столбца, если в нем присутствуют пропущенные значения NA. Это наш случай, так как в уроке ранее мы добавили строку для Люксембурга, и там было пропущено число источников n_sources. Как рассчитать средние значения без потерь? Добавить аргумент na.rm от английского NA remove, чтобы пропущенные значения опускались при подсчете среднего.
cpi %>% group_by(region) %>% summarise(N = n(), 
                                       `Mean CPI` = mean(cpi_score),
                                       `Sd CPI` = sd(cpi_score),
                                       `Mean N sources` = mean(n_sources, na.rm = TRUE))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 6 x 5
##   region     N `Mean CPI` `Sd CPI` `Mean N sources`
##   <chr>  <int>      <dbl>    <dbl>            <dbl>
## 1 AME       32       43.4    16.4              6.38
## 2 AP        31       44.9    20.0              6.94
## 3 ECA       19       34.8     8.54             7.11
## 4 MENA      18       39      16.9              6.61
## 5 SSA       49       32.2    12.6              6.94
## 6 WE/EU     31       66.1    14.5              8.37
Теперь все на месте, пропущенное значение в столбце n_sources игнорируется при расчете среднего.
На результаты, полученные с помощью summarise(), можно «наслаивать» новые сводные характеристики по группам. Другими словами, на основе столбцов в summarise() можно получать новые столбцы. Например, для оценки разброса данных, их вариации, часто используется показатель коэффициент вариации, который вычисляется как отношение стандартного отклонения к среднему значению. Воспользуемся функцией mutate() и применим ее после summarise() для того, чтобы поделить значения в Sd CPI на значения в Mean CPI:
cpi %>% group_by(region) %>% summarise(N = n(), 
                                       `Mean CPI` = mean(cpi_score),
                                       `Sd CPI` = sd(cpi_score),
                                       `Mean N sources` = mean(n_sources, na.rm = TRUE)) %>% 
  mutate(CV = `Sd CPI` / `Mean CPI`)
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 6 x 6
##   region     N `Mean CPI` `Sd CPI` `Mean N sources`    CV
##   <chr>  <int>      <dbl>    <dbl>            <dbl> <dbl>
## 1 AME       32       43.4    16.4              6.38 0.378
## 2 AP        31       44.9    20.0              6.94 0.446
## 3 ECA       19       34.8     8.54             7.11 0.246
## 4 MENA      18       39      16.9              6.61 0.433
## 5 SSA       49       32.2    12.6              6.94 0.392
## 6 WE/EU     31       66.1    14.5              8.37 0.220
Получилось! Коэффициент вариации, взятый по модулю, обычно лежит в интервале от 0 до 1 (хотя может быть и больше 1), и чем ближе значение к 1, тем выше разброс значений, тем более они разнообразные.
Помимо выдачи сводной информации по группам нас может интересовать более широкая задача — применение функций к каждой группе, избегая циклы. Например, мы можем захотеть выгрузить строки, соответствующие каждой группе, в отдельные файлы. Для этого мы можем воспользоваться сочетанием функций group_walk() и write_csv(). Функция group_walk() позволяет применить некоторую функцию к каждой группе. Мы запишем функцию для выгрузки датафреймов в файл с помощью формулы с несколькими аргументами. Аргументом .x в рамках group_walk() обозначается группа строк, над которыми мы проделываем операцию, аргументом .y — таблица с названиями столбцов. Формула начинается с символа ~. Реализуем:
cpi %>% group_by(region) %>% 
  group_walk(~write_csv(.x, paste0(.y$region, ".csv")))
Ставим ~, сообщая R, что впереди указывается формула. Пишем функцию write_csv() для выгрузки в строк файл. На первом месте указываем датафрейм, который выгружаем — строки .x, на втором — название файла, которое мы получаем путем склеивания через paste0() названия региона из столбцов .y и расширения .csv.
Однако при запуске кода выше мы получаем ошибку! R не может найти путь WE/EU.csv. Это ожидаемо, это происходит из-за наличия слэша в названии региона. R считает, что это путь к папке WE и файлу EU.csv. Давайте добавим код для замены этого слэша на знак подчеркивания — воспользуемся функцией str_replace():
cpi %>% group_by(region) %>% 
  group_walk(~write_csv(.x, paste0(str_replace(.y$region, "/", "_"), ".csv")))
Готово! Можем проверить, что файлы созданы и что в них действительно хранятся данные по разным регионам. [Проверяем — открываем пару новых файлов в папке.]
Библиотека stargazer часто используется для выгрузки результатов статистических тестов и моделей, значения в которых сопровождаются звездочками, отмечающими уровень статистической значимости результатов. Из-за этого библиотека имеет такое название stargazer, star – «звезда», gaze – «глазеть». Но эту библиотеку можно использовать и для выгрузки таблиц с обычными описательными статистиками. Установим библиотеку и обратимся к ней:
install.packages("stargazer")
library(stargazer)
Для выгрузки описательных статистик используется функция stargazer(). По умолчанию эта функция формирует выдачу в виде кода на языке разметки LaTeX прямо в консоли. Но если вы не знакомы с LaTeX, не стоит беспокоиться: мы сейчас сделаем так, чтобы R выгружал выдачу в виде файла в формате htm, который легко открывается и редактируется в Word или аналогичных редакторах (Libre Office, Open Office). Попросим stargazer сформировать описательные статистики по датафрейму cpi:
stargazer(cpi, type = "html", out = "summary.htm") 
| Statistic | N | Mean | St. Dev. | Min | Pctl(25) | Pctl(75) | Max | 
| cpi_score | 180 | 43.167 | 18.960 | 9 | 29 | 56 | 87 | 
| cpi_rank | 180 | 88.967 | 51.656 | 1 | 44 | 130 | 180 | 
| n_sources | 179 | 7.061 | 1.796 | 3.000 | 6.000 | 8.000 | 10.000 | 
| cpi_perc | 179 | 0.430 | 0.188 | 0.090 | 0.290 | 0.560 | 0.870 | 
| asia | 180 | 0.278 | 0.449 | 0 | 0 | 1 | 1 | 
| eu | 180 | 0.172 | 0.379 | 0 | 0 | 0 | 1 | 
Пропишем тип файла html и укажем название файла summary.htm. В консоли отобразился исходный код выдачи, но он нас не интересует, поскольку в рабочей папке появился файл summary.htm. По умолчанию, как и HTML-страницы, с которыми мы сталкиваемся в интернете, этот файл открывается в браузере. Но при желании всегда можно кликнуть правой клавишей и Открыть с помощью, а затем выбрать Word или иной текстовый редактор. Я выберу Libre Office и открою файл в нем.
В полученной таблице по строкам идут названия числовых показателей, а по столбцам – их характеристики: число заполненных значений (N), среднее (Mean), стандартное отклонение (St.Dev.), минимум (Min), нижний квартиль (Pctl25) и верхний квартиль (Pctl75) и максимум (Max). При желании вид выдачи можно модифицировать. Давайте запросим help и посмотрим на доступные опции.
help(stargazer)
Опций много. Для примера давайте сделаем следующее. Добавим заголовок таблицы (аргумент title), комментарий внизу таблицы (аргумент notes), включим медиану (аргумент median).
stargazer(cpi, type = "html", out = "summary.htm", title = "CPI 2019", notes = "Index by Transparency International", median = TRUE)
| Statistic | N | Mean | St. Dev. | Min | Pctl(25) | Median | Pctl(75) | Max | 
| cpi_score | 180 | 43.167 | 18.960 | 9 | 29 | 39.5 | 56 | 87 | 
| cpi_rank | 180 | 88.967 | 51.656 | 1 | 44 | 88 | 130 | 180 | 
| n_sources | 179 | 7.061 | 1.796 | 3.000 | 6.000 | 7.000 | 8.000 | 10.000 | 
| cpi_perc | 179 | 0.430 | 0.188 | 0.090 | 0.290 | 0.390 | 0.560 | 0.870 | 
| asia | 180 | 0.278 | 0.449 | 0 | 0 | 0 | 1 | 1 | 
| eu | 180 | 0.172 | 0.379 | 0 | 0 | 0 | 0 | 1 | 
| Index by Transparency International | ||||||||
Проверяем изменения в файле. Отлично, все изменения были учтены!
Тут может возникнуть вопрос: а как выгрузить выдачу, полученную нами с помощью tidyverse? Например, выдачу с описательными статистиками по группам? Очень просто. «Выключить» в stargazer() формирование собственного описания, принятого по умолчанию. Давайте сформируем выдачу со сводной информацией и посмотрим, как это делается.
Воспользуемся выдачей из предыдущего урока и сохраним ее в переменную descr:
descr <- cpi %>% group_by(region) %>% summarise(N = n(),
`Mean CPI` = mean(cpi_score),
`Sd CPI` = sd(cpi_score))
## `summarise()` ungrouping output (override with `.groups` argument)
descr
## # A tibble: 6 x 4
##   region     N `Mean CPI` `Sd CPI`
##   <chr>  <int>      <dbl>    <dbl>
## 1 AME       32       43.4    16.4 
## 2 AP        31       44.9    20.0 
## 3 ECA       19       34.8     8.54
## 4 MENA      18       39      16.9 
## 5 SSA       49       32.2    12.6 
## 6 WE/EU     31       66.1    14.5
Теперь выставим аргумент summary = FALSE и сохраним выдачу в новый файл groups.htm:
stargazer(descr, type = "html", out = "groups.htm", summary = FALSE)
| region | N | Mean CPI | Sd CPI | |
| 1 | AME | 32 | 43.375 | 16.3800626254268 | 
| 2 | AP | 31 | 44.8709677419355 | 20.0295480652691 | 
| 3 | ECA | 19 | 34.7894736842105 | 8.54126550191885 | 
| 4 | MENA | 18 | 39 | 16.8836851288281 | 
| 5 | SSA | 49 | 32.2448979591837 | 12.6483375262076 | 
| 6 | WE/EU | 31 | 66.0645161290323 | 14.5165089556017 | 
Готово! Откроем файл и проверим. Все на месте. Осталось навести красоту – сделать число знаков после запятой равное 2, чтобы избавиться от ненужной в данном случае детализации и привести выдачу в более читаемый вид.
descr <- cpi %>% group_by(region) %>% summarise(N = n(),
`Mean CPI` = round(mean(cpi_score), 2),
`Sd CPI` = round(sd(cpi_score), 2))
## `summarise()` ungrouping output (override with `.groups` argument)
stargazer(descr, type = "html", out = "groups.htm", summary = FALSE)
| region | N | Mean CPI | Sd CPI | |
| 1 | AME | 32 | 43.38 | 16.38 | 
| 2 | AP | 31 | 44.87 | 20.03 | 
| 3 | ECA | 19 | 34.79 | 8.54 | 
| 4 | MENA | 18 | 39 | 16.88 | 
| 5 | SSA | 49 | 32.24 | 12.65 | 
| 6 | WE/EU | 31 | 66.06 | 14.52 | 
Теперь все в порядке.