Библиотека dplyr
- библиотека для удобной работы с базами данных. С ее помощью можно более быстро получать описание базы данных, сохранять полученные результаты и группировать данные по определенному признаку. Научиться работать с это библиотекой несложно, нужно только понять общую логику, познакомиться с особыми операторами и функциями, а также немного попрактиковаться.
Для начала установим библиотеку и обратимся к ней:
install.packages("dplyr")
library(dplyr)
Теперь мы готовы к работе. Загрузим базу с результатами плебисцита в Чили, с которой мы работали на прошлом семинаре.
chile <- read.csv("Chile.csv")
Некоторые функции, встроенные в библиотеку, похожи на обычные функций, которые мы использовали на прошлом занятии. Например, функция select()
, которая позволяет выбрать интересующие нас столбцы в базе данных:
sh_chile <- select(chile, sex, age, income, vote)
View(sh_chile)
Также с помощью select()
можем исключить некоторые столбцы, которые нас не интересуют, поставив перед вектором столбцов минус (так же, как и раньше!):
sh_chile2 <- select(chile, -c(X, region, population))
View(sh_chile2)
Столбцы можно выбирать по названиям, если столбцы идут подряд:
head(select(chile, sex:vote)) # столбцы от sex до vote
## sex age education income statusquo vote
## 1 M 65 P 35000 1.00820 Y
## 2 M 29 PS 7500 -1.29617 N
## 3 F 38 P 15000 1.23072 Y
## 4 F 49 P 35000 -1.03163 N
## 5 F 23 S 35000 -1.10496 N
## 6 F 28 P 7500 -1.04685 N
Если хотим отобрать интересующие нас наблюдения, нам потребуется другая функция - filter()
. Отберем, например, респондентов не моложе 45 лет:
old_ch <- filter(chile, age >= 45)
View(old_ch)
А теперь отберем респондентов мужского пола, не моложе 45 лет:
old_ch <- filter(chile, age >= 45 & sex == "F")
View(old_ch)
Казалось бы, зачем использовать библиотеку dplyr
, если результаты пока несильно отличаются от того, что мы делали на прошлом занятии без всяких библиотек? На самом деле, смысл использовать ее есть. И сейчас мы переходим к самому интересному.
В библиотеке dplyr
есть особый оператор %>%
, который позволяет выполнять операции пошагово. Смысл этого оператора такой: возьми, то, что слева от %>%
и передай это на вход функции, стоящей справа от %>%
. Посмотрим на простом примере:
chile %>% View
Взять базу chile
и подать ее на вход функции View
. Как можно заметить, во View
уже нет ни скобок, ни названия базы, потому что они и не нужны – R и так знает, с чем ему работать.
Рассмотрим другой пример. Возьмем базу chile
, сначала выберем столбцы sex, age, income и vote, а потом запросим несколько первых строк базы:
chile %>%
select(sex, age, income, vote) %>%
head
## sex age income vote
## 1 M 65 35000 Y
## 2 M 29 7500 N
## 3 F 38 15000 Y
## 4 F 49 35000 N
## 5 F 23 35000 N
## 6 F 28 7500 N
В библиотеке dplyr
есть несколько других интересных и полезных функций. Например, arrange()
– функция, которая сортирует базу данных в соответствии со значениями переменной (или переменных), расположенных по возрастанию (если переменная текстовая, то по алфавиту). Отсортируем базу по показателю statusquo
и посмотрим на первые несколько строк:
chile %>% arrange(statusquo) %>% head
## X region population sex age education income statusquo vote
## 1 788 C 175000 F 64 P NA -1.80301 U
## 2 2660 M 25000 M 27 S 7500 -1.74401 <NA>
## 3 2074 SA 250000 F 21 PS 35000 -1.72594 N
## 4 2445 SA 250000 F 42 S 35000 -1.48144 <NA>
## 5 1956 SA 250000 M 27 S 7500 -1.34392 N
## 6 464 C 250000 F 22 S 7500 -1.33198 N
А теперь на последние:
chile %>% arrange(statusquo) %>% tail
## X region population sex age education income statusquo vote
## 2695 1569 S 125000 F 59 P NA NA Y
## 2696 1774 SA 250000 F 63 P NA NA U
## 2697 1777 SA 250000 M 49 <NA> NA NA <NA>
## 2698 1789 SA 250000 F 28 PS 75000 NA U
## 2699 1988 SA 250000 F 21 PS 35000 NA A
## 2700 2548 SA 250000 F 42 P 15000 NA U
Другая полезная функция – mutate()
– используется для создания и добавлению в базу данных новой переменной. Создадим переменную log_income
– натуральный логарифм дохода респондентов.
chile %>%
mutate(log_income = log(income)) %>%
View
Если теперь мы посмотрим на базу chile
привычным образом, нас будет ждать сюрприз:
View(chile)
Переменной log_income
в базе нет! Почему? Дело в том, что когда мы проделываем что-то с базой с помощью dplyr
и не сохраняем результат, изменения в самой базе не происходят. Как сохранить изменения? Очень просто: как всегда, сохранить результат в переменную, в которой хранится база:
chile <- chile %>%
mutate(log_income = log(income))
Добавлять можно и более одной переменной за раз:
chile <- chile %>%
mutate(log_income = log(income), log_population = log(population))
View(chile)
Теперь у нас в базе данных есть две переменные, которые начинаются с log
. В dplyr
есть функция, которая позволяет выбрать столбцы, названия которых начинаются одинаково.
chile %>%
select(starts_with("log_")) %>%
head
## log_income log_population
## 1 10.463103 12.07254
## 2 8.922658 12.07254
## 3 9.615805 12.07254
## 4 10.463103 12.07254
## 5 10.463103 12.07254
## 6 8.922658 12.07254
Чтобы закрепить то, что мы уже успели разобрать, рассмотрим две задачи.
Задача 1. Выбрать строки в базе, для которых значения statusquo
не пустые (не NA) в переменной statusquo
, выбрать респондентов с доходом свыше 35000, отсортировать строки в базе по возрасту респондентов и посмотреть на базу данных.
Решение.
chile %>%
filter(!is.na(statusquo), income > 35000) %>%
arrange(age) %>%
View
Сначала мы выберем те строки в базе, для которых значения statusquo
не пустые (is.na
и помним про отриание - восклицательный знак), а заодно выберем респондентов с доходом более 35000. Затем с помощью arrange()
отсортируем строки по значениям age
. И, наконец, посмотрим на базу данных через View
.
Задача 2. Выбрать строки в базе, для которых значения statusquo
не пустые (не NA), выбрать тех респондентов, которые голосовали за или против Пиночета (значения ‘Y’ или ‘N’ в vote
), выбрать столбцы region
, statusquo
и vote
, а затем вывести на экран первые 10 строк.
chile %>%
filter(!is.na(statusquo), vote == "Y", vote == "N") %>%
select(region, statusquo, vote) %>%
head(10)
## [1] region statusquo vote
## <0 rows> (or 0-length row.names)
Сейчас речь пойдет, пожалуй, о самых полезных функциях dplyr :)
При работе с данными мы часто сталкиваемся с тем, что нам нужно получить какую-то сводную информацию по переменным. Для этого существует функция summarise()
. Попробуем пока получить общее число строк в базе данных:
chile %>% summarise(total = n())
## total
## 1 2700
Функция n()
универсальна, она используется для подсчета элементов. К ней мы еще вернемся.
Теперь сделаем что-нибудь более интересное. Определим минимальное, максимальное и среднее значение возраста респондентов в этой базе.
chile %>% summarise(avg_age = mean(age),
min_age = min(age),
max_age = max(age))
## avg_age min_age max_age
## 1 NA NA NA
Почему R не хочет ничего считать? Потому что в переменно age
есть пропущенные значения! Как справиться с этой проблемой? Самое простое и очевидное – удалить NA из базы. Но это необязательно. У многих функций в R, работающих с переменными, есть параметр na.rm
, который позволяет зафиксировать, исключать ли пропущенные значения (rm - remove) при подсчете или нет.
chile %>% summarise(avg_age = mean(age, na.rm = TRUE),
min_age = min(age, na.rm = TRUE),
max_age = max(age,na.rm = TRUE))
## avg_age min_age max_age
## 1 38.54872 18 70
Теперь все в порядке.
Часто необходимо получить сводную информацию не по всем наблюдениям в базе, а по определенной группе. Для этого сначала нужно сгруппировать данные, основываясь на значениях какой-нибудь переменной. Воспользуемся функцией group_by()
и посмотрим, сколько в базе респондентов из разных регионов:
chile %>% group_by(region) %>% summarise(count_reg = n())
## # A tibble: 5 x 2
## region count_reg
## <fctr> <int>
## 1 C 600
## 2 M 100
## 3 N 322
## 4 S 718
## 5 SA 960
А теперь посмотрим на средний возраст респондентов из разных регионов:
chile %>% group_by(region) %>% summarise(avg_income = mean(age, na.rm = TRUE))
## # A tibble: 5 x 2
## region avg_income
## <fctr> <dbl>
## 1 C 38.36667
## 2 M 36.66000
## 3 N 38.67702
## 4 S 37.62813
## 5 SA 39.50574
Число наблюдений можно посчитать и по-другому – с помощью функции tally
:
chile %>% group_by(sex) %>% summarise(count_sex = n())
## # A tibble: 2 x 2
## sex count_sex
## <fctr> <int>
## 1 F 1379
## 2 M 1321
chile %>% group_by(sex) %>% tally()
## # A tibble: 2 x 2
## sex n
## <fctr> <int>
## 1 F 1379
## 2 M 1321