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 |
Теперь все в порядке.