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