Как перестать бояться и полюбить R. Часть 3. Основные элементы
В этой статье мы поговорим об основных элементах языка R. Я выделил для рассмотрения: общую часть, типы и структуры данных, функции, библиотеки и визуализацию.
Общая часть
Стоит начать с того, что R интерпретируемый язык, также как и Python. А это значит, что для выполнения кода нам не нужно писать целую программу, мы можем выполнять любую команду в произвольном порядке. Вторая важная особенность R это то, что переменные не требуют объявлять тип хранимых данных при их создании. Далеко не все языки программирования такие, но именно эти особенности делают R более понятным и доступным для непрограммистов.
От многих других языков, в том числе от Python, R отличается тем, что в нём индексация начинается не с 0, а с 1. Что, на мой взгляд, тоже более понятно на интуитивном уровне для людей нетехнических профессий. Я учил Python после R и переход к нумерации от 0 поначалу ломал мою голову.
Ещё у R известен тем, что имеет оригинальный оператор присвоения <- (на Win alt + -). Хотя высоким стилем и стандартом считается именно его использование, вы можете достигать того же результата с помощью знака =.
# Создаём вектор x, присваиваем ему значения “a, b, c”.
x <- c('a', 'b', 'c')
# Просим показать первый элемент вектора
x[1]
[1] "a"В R удобно писать конвейеры с помощью оператора |> (на Win ctrl+ shift + m ), что позволяет передавать результаты предыдущей операции для выполнения следующей. Проще всего отразить принцип на примере.
# Вариант без оператора |> numbers <- 1:10 # Создаем последовательность чисел от 1 до 10 my_sum <- sum(numbers) # Суммируем эту последовательность my_sqrt <- sqrt(my_sum) # Извлекаем корень из суммы # Вариант с оператором |> numbers |> sum() |> sqrt() [1] 7.416198
Есть два основных способа написать управляющую конструкцию ЕСЛИ … ТО. Обратите внимание в этом примере, что в R равенство обозначается двойным знаком ==, что отличает его от одинарного знака =, который можно использовать для присвоения.
# Проверяем, что два плюс два равно четыре.
# Первый способ
if (2 + 2 == 4) {
print("Верное равенство")
}
# Второй способ
ifelse(2 + 2 == 4, "Верное равенство", "Неверное равенство")
[1] "Верное равенство"И существует несколько способов написать цикл, здесь я покажу только вариант с FOR.
# Печатаем числа от 1 до 5
for (i in 1:5) {
print(i)
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5Типы и структуры данных
Существуют разные классификации типов данных в R, я выделю следующие:
- Numeric (числовой) – любые числа с произвольным количеством знаков после запятой.
- Integer (целочисленный) – только целые числа.
- Logical (логический) – логические значения TRUE (правда, 1) и FALSE (ложь, 0).
- Character (текстовый) – любой текст.
- Factors (факторный) – любой текст, который представляет группы или уровни переменной.
От типов данных зависит то, как будет обрабатываться наша переменная во время анализа. К примеру, если мы хотим построить регрессию и разделить участников исследования по полу, то переменная пол, должна быть закодирована как факторная, в этом случае R автоматически поймет, как обрабатывать её в регрессии.
Чем отличается R на базовом уровне от Python – это тем, что его ядровые структуры данных идеально подходят для аналитиков. Да, в Python существует библиотека Pandas и прочие, но это уже реакция и надстройка, в то время как в R это все предусмотрено с самого начала.
Vectors (векторы): коллекция элементов одного типа данных.
# Векторы создаются с помощью функции c()
c(1, 2 , 3, 4)
[1] 1 2 3 4
c('a', 'b', 'c', 'd')
[1] "a" "b" "c" "d"Matrices (матрицы): двумерные наборы элементов одного и того же типа данных.
# Используем функцию matrix() для создания матрицы
matrix(data = c(10, 15, 20, 25),
nrow = 2,
ncol = 2)
[,1] [,2]
[1,] 10 20
[2,] 15 25Arrays (массивы): многоуровневых наборы элементов, обобщение матрицы.
# Команда array() создает массивы
array(data = c(1:24),
dim = c(4, 3, 2))
, , 1
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
, , 2
[,1] [,2] [,3]
[1,] 13 17 21
[2,] 14 18 22
[3,] 15 19 23
[4,] 16 20 24Lists (списки): список элементов, который может состоять из разных типов и структур данных.
# Для создания списка используем list()
list(name = "Саша",
age = 36,
scores = c(88, 94, 76),
is_student = FALSE)
$name
[1] "Саша"
$age
[1] 36
$scores
[1] 88 94 76
$is_student
[1] FALSEData Frames (таблицы данных aka датафреймы): самая привычная структура данных для аналитиков, где каждая колонка представляет переменную, а строки наблюдения.
# Таблицу создаем с помощью функции data.frame()
data.frame(
ID = 1:4,
Name = c("Иван", "Мария", "Михаил", "Людмила"),
Age = c(25, 30, 35, 40),
Salary = c(50000, 55000, 60000, 65000)
)
ID Name Age Salary
1 1 Иван 25 50000
2 2 Мария 30 55000
3 3 Михаил 35 60000
4 4 Людмила 40 65000
Несколько примеров, как можно выбирать данные в датафрейме. Предположим, что мы записали наш датафрейм в переменную df.
# Выбрать колонку по названию, используем нотацию: датафрейм$колонка df$ID [1] 1 2 3 4 # Выбрать строку по номеру [номер строки, номер колонки] df[1,] ID Name Age Salary 1 1 Иван 25 50000 # Выбрать колонку по номеру [номер строки, номер колонки] df[,2] [1] "Иван" "Мария" "Михаил" "Людмила" # Выбрать данные в первой колонке, третье строке [номер строки, номер колонки] > df[1,3] [1] 25
Невозможно удержать в голове какие аргументы должны подаваться в каждую функцию, но всегда можно вызвать справку по любой функции R. Для этого достаточно поставить ? перед названием функции, к примеру, справка по data.frame():
Функции
Мы посмотрели с вами на множество готовых функций и дальше будем работать с ними ещё больше, но также мы можем писать свои собственные функции. В языках программирования функции меньше похожи на функции в математике, а больше похожи на белки в нашем организме, простыми словами это машины, которые выполняют какие-то действия по определенной логике.
# Создадим функцию, которая возводит аргумент во вторую степень
my_function <- function(x) {
squared <- x^2
return(squared)
}
# Вызовем функцию с аргументом 4
my_function(4)
[1] 16Библиотеки
В прошлой статье [1] мы говорили про библиотеки и их установку. Конечно, правильно называть их пакетами, но так сложилось, что в практике чаще употребляется именно слово библиотека, поэтому я позволяю себе такую нестрогость.
#Установка библиотеки. Выполняется один раз.
install.packages("ggplot2")
#Подключение библиотеки. Выполняется при каждом запуске скрипта.
library(ggplot2)В библиотеках хранятся не только функции, но часто и наборы данных, что очень удобно для изучения анализа данных. Я уже это говорил, но повторю мысль, что крутизна R и его привлекательность для аналитиков во многом заключается именно в библиотеках, потому как сообщество неравнодушных людей создает новые функции и библиотеки именно для R. Впечатлитесь вот этим списком [2] и вот этой картинкой [3]:
Визуализация
В R существует встроенные графики, но библиотека ggplot2 [4] задала стандарт визуализации в R. В отличие от многих книг мы не будем использовать базовые графики, а сразу начнем работу с ggplot2. Графики в ggplot2 строятся слоями, которые позволяют сильно кастомизировать визуализацию. Давайте рассмотрим пример используя данные Кейта МакНалти [5].
library(ggplot2) # Подключаем ggplot2 для графиков
library(peopleanalyticsdata) # Отсюда возьмем данные
# Данные к книге Кейта МакНалти
df <- peopleanalyticsdata::salespeople
# Строим скаттерплот
ggplot(df, aes(x = customer_rate, y = sales)) + #на оси x = оценка клиента, на оси y = продажи
geom_point(size = 3, color = "purple") + #тип графика скаттерплот
labs(title = "Связь между оценкой клиента и уровнем продаж", #подписи графика и осей
x = "Оценка клиента",
y = "Продажи") +
theme_minimal() + #тема графика
theme(panel.grid.major = element_blank(), #отключаем сетку
panel.grid.minor = element_blank())- Ботвин А. Как перестать бояться и полюбить R. Часть 2. Установка
- https://cran.r-project.org/web/packages/available_packages_by_name.html
- Gizem Korkmaz. Modeling the impact of Python and R packages using dependency and contributor network
- https://ggplot2.tidyverse.org/
- Keith McNulty. Handbook of Regression Modeling in People Analytics