Как перестать бояться и полюбить 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 25
Arrays (массивы): многоуровневых наборы элементов, обобщение матрицы.
# Команда 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 24
Lists (списки): список элементов, который может состоять из разных типов и структур данных.
# Для создания списка используем 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] FALSE
Data 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