Собственно, сам R
RStudio - среда для разработки (IDE) на R
Онлайн IDE для R — на тот случай, если у вас не установлен R:
linmodr
создайте папку data
,
где будут храниться все файлы с данными для анализа.В итоге у вас должно получиться примерно это:
C:\linmodr\
C:\linmodr\data\
Все настройки RStudio находятся в меню Tools -> Global Options
General
убираем галочку
Restore .RData into workspace at startup
, и меняем
Save workspace to .RData on exit
- Never
Code
ставим галочку рядом с опцией
Soft-wrap R source files
Комментарии в текстах программ обозначаются символом #
# это комментарии, они не будут выполняться
Ctrl + Shift + C
- закомментировать/раскомментировать
выделенный фрагмент кодаCtrl + Enter
- отправляет активную строку из текстового
редактора в консоль, а если выделить несколько строк, то будет выполнен
этот фрагмент кода.Tab
или Ctrl + Space
- нажмите после того
как начали набирать название функции или переменной, и появится список
автоподстановки. Это помогает печатать код быстро и с меньшим
количеством ошибок.setwd
и
нажать F1
?setwd
help()
help("setwd")
2+2
## [1] 4
1024/2
## [1] 512
1:10
## [1] 1 2 3 4 5 6 7 8 9 10
34*4
## [1] 136
2^4
## [1] 16
sqrt(27)
## [1] 5.196152
Оператор присваивания это символ стрелочки <-
. Он
работает справа налево, это значит, что значение выражения в его правой
части присваивается объекту в левой части.
Переменные - это такие контейнеры, в которые можно положить разные данные и даже функции.
Имена переменных могут содержать латинские буквы обоих регистров, символы точки . и подчеркивания _ , а так же цифры. Имена переменных должны начинаться с латинских букв. Создавайте понятные и “говорящие” имена переменных.
<- 1024 / 2
var_1 1238 * 3 -> var_2
var_2
## [1] 3714
Как выбрать название переменной?
a
- плохо, и даже b
, с
, или
х
. Но в некоторых случаях допустимо:)var1
- плохо, но уже лучшеvar_1
- плохо, но уже лучшеshelllength
- говорящее, но плохо читаетсяshell_length
, wing_colour
или
leg_num
- хорошие говорящие и читабельные названияДанные в R можно хранить в виде разных объектов.
В результате выполнения следующих команд числа. Одно выражение - одно значение.
23
## [1] 23
sqrt(25)
## [1] 5
На самом деле, эти величины - просто векторы единичной длины
Векторы - один объект, внутри которого несколько значений.
1:10 # от одного до 10
## [1] 1 2 3 4 5 6 7 8 9 10
-5:3 # от -5 до 3
## [1] -5 -4 -3 -2 -1 0 1 2 3
seq()
создает последовательности из чиселseq(from = 1, to = 5, by = 0.5)
## [1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
c()
- от англ. concatenate. Следите, чтобы было
английское си, а не русское эс:).# посмотрите хелп к функции ?c
Функция c
принимает несколько (произвольное количество)
аргументов, разделенных запятыми. Она собирает из них вектор.
c(2, 4, 6)
## [1] 2 4 6
c(-9.3, 0, 2.17, 21.3)
## [1] -9.30 0.00 2.17 21.30
Векторы можно хранить в переменных для последующего использования
<- -11:12 # численный вектор от -11 до 12 сохранен в переменной vect_num
vect_num <- c(1.3, 1.7, 1.2, 0.9, 1.6, 1.4) # численный вектор, сохранен в переменной vect_num_1 vect_num_1
При помощи оператора []
, можно обратится к некоторым
элементам вектора. В квадратных скобках вам нужно указать один или
несколько порядковых номеров элементов
1] # первый элемент в векторе vect_num vect_num[
## [1] -11
10] # 10-й элемент vect_num[
## [1] -2
22] vect_num[
## [1] 10
Если вам нужно несколько элементов, то их нужно передать квадратным скобкам в виде вектора. Например, нам нужны элементы с 3 по 5. Вот вектор, который содержит значения 3, 4 и 5.
3:5
## [1] 3 4 5
Если мы его напишем в квадратных скобках, то добудем элементы с такими порядковыми номерами
3:5] vect_num[
## [1] -9 -8 -7
Аналогично, если вам нужны элементы не подряд, то передайте вектор с номерами элементов, который вы создали при помощи функции c() c(2, 4, 6) # это вектор содержащий 2, 4 и 6, поэтому
c(2, 4, 6)] # возвращает 2-й, 4-й и 6-й элементы vect_num[
## [1] -10 -8 -6
c(1, 10, 20)] # возвращает 1-й, 10-й и 20-й элементы vect_num[
## [1] -11 -2 8
Вектор - одномерный объект. У его элементов только один порядковый номер (индекс). Поэтому при обращении к элементам вектора нужно указывать только одно число или один вектор с адресами.
Правильно:
c(1, 2, 5)] # возвращает 1-й, 3-й и 5-й элементы vect_num[
## [1] -11 -10 -7
Но R выдаст ошибку, если при обращении к вектору, вы не создавали вектор, а просто перечислили номера элементов через запятую.
1, 3, 5] # ошибка
vect_num[15, 9, 1] # ошибка vect_num[
c(15, 9, 1)] # правильно vect_num[
## [1] 3 -3 -11
При помощи функции c() можно объединять несколько векторов в один вектор
c(1, 1, 5:9)
## [1] 1 1 5 6 7 8 9
c(vect_num, vect_num)
## [1] -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
## [20] 8 9 10 11 12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2
## [39] 3 4 5 6 7 8 9 10 11 12
c(100, vect_num)
## [1] 100 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6
## [20] 7 8 9 10 11 12
Добываем 1, 3, 5 и с 22 по 24 элементы
c(1, 3, 5, 22:24)] vect_num[
## [1] -11 -9 -7 10 11 12
Уже видели в прошлом разделе.
Каждый текстовый элемент (говорят “строка” - string или character) должен быть окружен кавычками - двойными или одинарными.
"это текст"
## [1] "это текст"
'это тоже текст'
## [1] "это тоже текст"
Текстовые значения можно объединять в вектора.
Это текстовый вектор
<- c("red", "orange", "yellow", "green", "blue", "violet")
rainbow # весь вектор rainbow
## [1] "red" "orange" "yellow" "green" "blue" "violet"
Добываем первый и последний элементы
В данном случае я точно знаю, что их 6, мне нужны 1 и 6.
c(1, 6)] rainbow[
## [1] "red" "violet"
Добываем элементы с 3 по 6
Если у вас вдруг слишком короткий вектор в этом задании, то можно склеить новый из двух
<- c(rainbow, rainbow)
double_rainbow double_rainbow
## [1] "red" "orange" "yellow" "green" "blue" "violet" "red" "orange"
## [9] "yellow" "green" "blue" "violet"
3:6] # элементы с 3 по 6 rainbow[
## [1] "yellow" "green" "blue" "violet"
TRUE # истина
## [1] TRUE
FALSE # ложь
## [1] FALSE
Для ленивых - можно сокращать первыми заглавными буквами. Но лучше так не делать, чтобы читать программы было легче.
c(T, T, T, T, F, F, T, T)
## [1] TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE
Логический вектор
c(TRUE, TRUE, TRUE, FALSE, FALSE, TRUE)
## [1] TRUE TRUE TRUE FALSE FALSE TRUE
Еще логический вектор
<- c(FALSE, TRUE) short_logical_vector
Создаем длинный логический вектор.
Чтобы создавать длинные вектора из повторяющихся элементов, можно использовать функцию rep()
?rep
rep(x = 1, times = 3) # 1 повторяется 3 раза
## [1] 1 1 1
rep(x = "red", times = 5) # "red" повторяется 5 раз
## [1] "red" "red" "red" "red" "red"
rep(x = TRUE, times = 2) # TRUE повторяется 2 раза
## [1] TRUE TRUE
В R названия аргументов функций можно не указывать, если вы используете аргументы в том же порядке, что прописан в help к этой функции.
rep(TRUE, 5) # TRUE повторяется 5 раз, аргументы без названий
## [1] TRUE TRUE TRUE TRUE TRUE
Создаем логический вектор, где TRUE повторяется 3 раза, FALSE 3 раза и TRUE 4 раза. Результат сохраняем в переменной vect_log
<- c(rep(TRUE, 3), rep(FALSE, 3), rep(TRUE, 4))
vect_log vect_log
## [1] TRUE TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE TRUE
Логические векторы создаются при проверке выполнения каких либо
условий, заданных при помощи логических операторов (>
,
<
, ==
, !=
, >=
,
<=
, !
, &
, |
).
Такие векторы можно использовать для фильтрации данных
Вспомните, у нас был вот такой текстовый вектор
double_rainbow
## [1] "red" "orange" "yellow" "green" "blue" "violet" "red" "orange"
## [9] "yellow" "green" "blue" "violet"
Задача 1. Допустим, мы хотим из этого вектора извлечь только желтый цвет.
Мы можем создать логический вектор, в котором TRUE будет только для 3-го и 9-го элементов
<- double_rainbow == "yellow"
f_yellow f_yellow
## [1] FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
Этот логический вектор-фильтр мы можем использовать для извлечения
данных из double_rainbow
double_rainbow[f_yellow]
## [1] "yellow" "yellow"
Задача 2. Допустим, мы хотим извлечь из double_rainbow желтый и синий Желтый фильтр у нас уже есть, поэтому мы создадим фильтр для синего.
<- double_rainbow == "blue" f_blue
Выражение “желтый или синий” можно записать при помощи логического
“или” (|
)
| f_blue f_yellow
## [1] FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE TRUE FALSE TRUE FALSE
Задача решена, мы извлекли желтый и синий цвета.
| f_blue] double_rainbow[f_yellow
## [1] "yellow" "blue" "yellow" "blue"
То же самое можно было бы записать короче.
В одну строку — совершенно нечитабельно:
== "yellow" | double_rainbow == "blue"] double_rainbow[double_rainbow
## [1] "yellow" "blue" "yellow" "blue"
Фильтр отдельно — читается лучше:
<- double_rainbow == "yellow" | double_rainbow == "blue"
f_colours double_rainbow[f_colours]
## [1] "yellow" "blue" "yellow" "blue"
У нас был числовой вектор
vect_num
## [1] -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
## [20] 8 9 10 11 12
Задача 3. Давайте извлечем из числового вектора vect_num
только значения больше 0
> 0] vect_num[vect_num
## [1] 1 2 3 4 5 6 7 8 9 10 11 12
Задача 4. Давайте извлечем из вектора vect_num
все
числа, которые либо меньше или равны -8, либо больше или равны 8
<- (vect_num <= -8) | (vect_num >= 8)
f_5_8 vect_num[f_5_8]
## [1] -11 -10 -9 -8 8 9 10 11 12
Факторы - это способ хранения дискретных (=категориальных данных). Например, если вы поймали 10 улиток и посмотрели их цвет. У большого количества улиток небольшое счетное количество возможных цветов.
<- c("red", "green", "green", "green", "yellow", "yellow", "yellow", "yellow")
snail_colours # это текстовый вектор. snail_colours
## [1] "red" "green" "green" "green" "yellow" "yellow" "yellow" "yellow"
Но цвет “желтый” обозначает одно и то же для каждой из улиток. Поэтому в целях экономии места можно записать цвета этих улиток в виде вектора, в котором численным значениям будут сопоставлены “этикетки” (называются “уровни” - levels) - названия цветов. Мы можем создать “фактор” цвет улиток.
factor(snail_colours)
## [1] red green green green yellow yellow yellow yellow
## Levels: green red yellow
уровни этого фактора
По умолчанию, R назначает порядок уровней по алфавиту. Можно изменить
порядок (см. help("factor")
). Нам это пригодится позже
# текстовый вектор double_rainbow
## [1] "red" "orange" "yellow" "green" "blue" "violet" "red" "orange"
## [9] "yellow" "green" "blue" "violet"
Создаем фактор из текстового вектора и складываем его в переменную
<- factor(double_rainbow) f_double_rainbow
Чтобы узнать, что за данные хранятся в переменной, используйте
функцию class()
class(f_double_rainbow)
## [1] "factor"
class(vect_log)
## [1] "logical"
class(vect_num)
## [1] "integer"
class(rainbow)
## [1] "character"
Встроенные константы в R: NA, NULL, NAN, Inf
Вот текстовый вектор с пропущенным значением
<- c("red", "orange", NA, "green", "blue", "violet") rainbow_1
Кстати, если попросили добыть из вектора номер элемента, которого там точно нет, то R выдаст NA, потому, что такого элемента нет
198] rainbow_1[
## [1] NA
Поэкспериментируем с векторами. Проверим, как работают арифметические операции
+ 2 vect_num
## [1] -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
* 2 vect_num
## [1] -22 -20 -18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14
## [20] 16 18 20 22 24
* (-2) vect_num
## [1] 22 20 18 16 14 12 10 8 6 4 2 0 -2 -4 -6 -8 -10 -12 -14
## [20] -16 -18 -20 -22 -24
^2 vect_num
## [1] 121 100 81 64 49 36 25 16 9 4 1 0 1 4 9 16 25 36 49
## [20] 64 81 100 121 144
Теперь посмотрим на встроенные константы в действии.
Создаем новый вектор для экспериментов
<- c(1, 3, NA, 7, 0, 22:24) NAs_NANs
Вот так он выглядит
NAs_NANs
## [1] 1 3 NA 7 0 22 23 24
Что произойдет с NA?
+ 2 # останется NA NAs_NANs
## [1] 3 5 NA 9 2 24 25 26
* 0 # останется NA NAs_NANs
## [1] 0 0 NA 0 0 0 0 0
/ 0 # останется NA NAs_NANs
## [1] Inf Inf NA Inf NaN Inf Inf Inf
Но в последнем случае вы увидите
NaN получится, если взять корень из отрицательного числа
sqrt(-1)
## Warning in sqrt(-1): NaNs produced
## [1] NaN
Вы уже видели массу функций, их легко узнать по скобкам после ключевого слова. Познакомимся еще с несколькими и научимся писать пользовательские функции. Пользовательские функции позволяют автоматизировать повторяющиеся действия и делают код легко читаемым.
Вот наш вектор
NAs_NANs
## [1] 1 3 NA 7 0 22 23 24
Длину вектора можно вычислить при помощи функции
length()
length(NAs_NANs)
## [1] 8
Сумму элементов вектора при помощи функции sum()
sum(NAs_NANs)
## [1] NA
Упс! Почему-то получилось NA
Чтобы узнать, почему и как это исправить - посмотрите в
help("sum")
. Выяснится, что у функции sum()
есть аргумент na.rm
, который по умолчанию принимает
значение FALSE
, то есть NA
не учитываются при
подсчете суммы.
Если мы передадим функции sum
аргумент
na.rm = TRUE
, то получится правильная сумма
sum(NAs_NANs, na.rm = TRUE)
## [1] 80
Та же история с функцией mean
mean(NAs_NANs, na.rm = TRUE)
## [1] 11.42857
Попробуем написать пользовательскую функцию mmean()
,
которая будет по умолчанию считать среднее значение элементов в векторе
с учетом пропущенных значений (NA
)
<- function(x){
mmean mean(x, na.rm = TRUE)
}
В этом коде: - mmean - переменная, название функции. В эту переменную
мы складываем функцию, которую создает функция function()
-
function()
- функция, которая делает функции. В скобках
перечисляются аргументы (названия переменных, которые мы передаем в
функцию, чтобы она что-то сделала с ними) - { }
- в
фигурных скобках тело функции - последовательность действий, которую
нужно сделать с аргументами
У больших функций бывает еще инструкция return()
,
которая сообщает, что именно должна возвращать наша функция. Вот как
выглядела бы наша функция с этой инструкцией
<- function(x){
mmean <- mean(x, na.rm = TRUE)
res return(res)
}
Проверим нашу функцию при помощи встроенной функции
mean(vect_num, na.rm = TRUE)
## [1] 0.5
mmean(vect_num)
## [1] 0.5
Работает
Датафрейм - один из способов хранения табличных данных в R. Создадим датафрейм.
Для этого, для начала, создадим векторы с данными для переменных.
<- 1:9 # числовой
len <- c(rep("green", 4), rep("red", 5)) # текстовый
col <- seq(from = 2, by = 2, to = 18) # числовой wid
Теперь сложим эти векторы в датафрейм
<- data.frame(Length = len, Width = wid, Colour = col) my_worms
Можно проверить, действительно мы создали объект класса data.frame
class(my_worms) # смотрим, действительно датафрейм
## [1] "data.frame"
Содержимое датафрейма можно просмотреть несколькими способами
# печать датафрейма my_worms
## Length Width Colour
## 1 1 2 green
## 2 2 4 green
## 3 3 6 green
## 4 4 8 green
## 5 5 10 red
## 6 6 12 red
## 7 7 14 red
## 8 8 16 red
## 9 9 18 red
View(my_worms) # просмотр в RStudio
head(my_worms)
## Length Width Colour
## 1 1 2 green
## 2 2 4 green
## 3 3 6 green
## 4 4 8 green
## 5 5 10 red
## 6 6 12 red
tail(my_worms)
## Length Width Colour
## 4 4 8 green
## 5 5 10 red
## 6 6 12 red
## 7 7 14 red
## 8 8 16 red
## 9 9 18 red
# fix(my_worms) # ручное редактирование. осторожно! избегайте его использовать, никаких документов о нем не останется
Вывод столбца-переменной при помощи оператора $ и имени переменной
$Length my_worms
## [1] 1 2 3 4 5 6 7 8 9
$Width my_worms
## [1] 2 4 6 8 10 12 14 16 18
У каждой ячейки в датафрейме есть координаты вида [строка, столбец]
2, 3] # вторая строка в 3 столбце my_worms[
## [1] "green"
2, ] # вторая строка целиком my_worms[
## Length Width Colour
## 2 2 4 green
1:9, 2] # строки с 1 по 9 во втором столбце my_worms[
## [1] 2 4 6 8 10 12 14 16 18
2] # второй столбец целиком my_worms[,
## [1] 2 4 6 8 10 12 14 16 18
Скаттерплот (точечный график) — по оси х и y непрерывные числовые величины
plot(x = my_worms$Width, y = my_worms$Length)
Боксплот — по оси х дискретная величина, по оси y значение непрерывной величины. Черта - медиана, коробка - 25 и 75 перцентили, усы - либо размах варьирования, либо 1.5 интерквартильных расстояния (1.5 высоты коробки), если есть “выбросы”.
plot(x = as.factor(my_worms$Colour), y = my_worms$Length)
Для настройки внешнего вида см graphical parameters в help
На самом деле, мы не будем пользоваться этой системой графики, но об этом в следующих сериях
В R есть более удобный (но, может быть, более многословный) пакет для рисования графиков — ggplot2. Чтобы использовать функции из пакета ggplot2, нужно его сначала установить.
Установка пакета в локальную библиотеку делается один раз. Поэтому
строку с install.packages()
не нужно включать в финальную
версию кода.
install.packages('ggplot2')
В текущей сессии работы в R пакет нужно активировать перед
использованием. Когда вы в следующий раз начнете работать с R, нужные
пакеты придется снова активировать. Поэтому строки с загрузкой пакетов
при помощи library()
обязательно должны остаться в
финальной версии кода.
library(ggplot2)
Нарисуем те же самые графики при помощи пакета ggplot2.
ggplot(data = my_worms) +
geom_point(aes(x = Width, y = Length))
ggplot(data = my_worms) +
geom_boxplot(aes(x = Colour, y = Length))
Добавляем для точек эстетику цвет (colour) из переменной Colour
ggplot(data = my_worms) +
geom_point(aes(x = Width, y = Length, colour = Colour))
Графики можно сохранять в переменных, и использовать потом
<- ggplot(data = my_worms) +
gg geom_point(aes(x = Width, y = Length, colour = Colour))
Чтобы вывести график, нужно напечатать название переменной.
gg
Можно менять темы оформления графика. Если тема нужна только один раз, то прибавляем ее к графику
+ theme_dark() gg
+ theme_light() gg
+ theme_classic() gg
Можно установить нужную тему до конца сессии.
theme_set(theme_bw())
gg
Подписи осей и легенд задает функция labs()
+ labs(x = "Ширина", y = "Длина", colour = "Цвет") gg
Графики можно делить на фасетки при помощи facet_wrap или facet_grid
+ facet_wrap(~Colour, nrow = 1) gg
Чтобы изменить подписи цветов, нужно изменить уровни соотв. фактора.
$col_rus <- factor(my_worms$Colour, levels = c("green", "red"), labels = c("Зеленый", "Красный"))
my_wormsggplot(data = my_worms) +
geom_point(aes(x = Width, y = Length, colour = col_rus)) +
labs(x = "Ширина", y = "Длина", colour = "Цвет") +
facet_wrap(~col_rus, nrow = 1)