Организация рабочего пространства

  1. Создайте папку, где будут храниться ВСЕ материалы курса. Например: Мы будем ее называть рабочей директорией. В эту папку помещайте ВСЕ файлы с кодом (с расширением .R).
  2. Внутри папки linmodr создайте папку data, где будут храниться все файлы с данными для анализа.

В итоге у вас должно получиться примерно это:

C:\linmodr\
C:\linmodr\data\

Настройка RStudio

Все настройки RStudio находятся меню Tools -> Global Options

  • Восстановление рабочено пространства из прошлого сеанса — это лучше отменить, т.к. обычно переменные-призраки очень мешают. На вкладке General убираем галочку Restore .RData into workspace at startup, и меняем Save workspace to .RData on exit - Never
  • Перенос длинных строк в окне кода — это удобно. На вкладке Code ставим галочку рядом с опцией Soft-wrap R source files

Комментарии

Комментарии в текстах программ обозначаются символом #

Полезные клавиатурные сокращения в RStudio

  • Ctrl + Shift + C - закомментировать/раскомментировать выделенный фрагмент кода
  • Ctrl + Enter - отправляет строку из текстового редактора в консоль, а если выделить несколько строк, то будет выполнен этот фрагмент кода.
  • Tab или Ctrl + Space - нажмите после того как начали набирать название функции или переменной, и появится список автоподстановки. Это помогает печатать код быстро и с меньшим количеством ошибок.

R как калькулятор, математические операции

Математические операторы + - / * ^

## [1] 4
## [1] 512
##  [1]  1  2  3  4  5  6  7  8  9 10
## [1] 136
## [1] 16

Задание 1

Поэкспериментируйте с другими математическими операторами (+ - / * ^).


Для некоторых операций в R есть функции, например:

## [1] 5.196152
## [1] 4.60517
## [1] 2

Задание 2

Найдите длину гипотенузы прямоугольного треугольника со сторонами 3 и 5 см.

## [1] 5.830952


Как получить помощь

  1. В RStudio можно поставить курсор на слово sqrt и нажать F1
  2. Перед названием функции можно напечатать знак вопроса и выполнить эту строку ?sqrt
  3. Можно воспользоваться функцией help()

Переменные

Переменные – это “контейнеры” для числовых (и разных других) значений.

Имена переменных могут содержать латинские буквы обоих регистров, символы точки . и подчеркивания _, а так же цифры. Имена переменных должны начинаться с латинских букв. Создавайте понятные и “говорящие” имена переменных.

Оператор присваивания это символ стрелочки <-. Он работает справа налево, это значит, что значение выражения в его правой части присваивается объекту в левой части.

Создаем переменную a и присваиваем ей значение 2, и переменную b со значением 5:

Переменные можно вызвать по имени:

## [1] 2
## [1] 5

С переменными можно проводить разные операции

## [1] 32
## [1] 6.6

Как выбрать название переменной?

  • a - плохо, и даже b, или х. Но в некоторых случаях допустимо:)
  • var1 - плохо, но уже лучше
  • var_1 - плохо, но уже лучше
  • shelllength - говорящее, но плохо читается
  • shell_length, wing_colour или leg_num - хорошие говорящие и читабельные названия

Осторожно, переменные можно случайно или намеренно перезаписать. Пока что b было равно 5, но если мы присвоим переменной b другое значение — оно изменится.

## [1] 5
## [1] 13

Код — это линейная последовательность действий. Переменные можно использовать только после того, как они были созданы.

Пример 1

Пример 2

Задание 3

Переставьте строки так, чтобы код можно было выполнить без ошибки.


Задание 4

Представьте прямоугольник. Его ширина 3 см, а длина на 5 см больше. Чему равен периметр? (В решении используйте переменные).


Структуры данных

Данные в R можно хранить в виде разных объектов.

В результате выполнения следующих команд числа. Одно выражение - одно значение.

## [1] 23
## [1] 5

На самом деле, эти величины - просто векторы единичной длины

Сначала разберемся с векторами, а другие структуры данных (датафреймы, списки, матрицы) будем изучать по мере знакомства с R .

Векторы

Вектор - один объект, внутри которого несколько значений.

Создание векторов при помощи :

Оператор : (двоеточие) используется для создания векторов, где значения следуют одно за другим с шагом 1 без пропусков.

##  [1]  1  2  3  4  5  6  7  8  9 10
## [1] -5 -4 -3 -2 -1  0  1  2  3

Задание 5

Создайте вектор из целых чисел от 1 до 100. Как вы думаете, что означают номера в квадратных скобках в начале каждой строки?

##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
##  [18]  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34
##  [35]  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51
##  [52]  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68
##  [69]  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85
##  [86]  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100


Создание векторов при помощи c()

Функция c() - от англ. concatenate. Следите, чтобы было английское си, а не русское эс:).

Функция c принимает несколько (произвольное количество) аргументов, разделенных запятыми. Она собирает из них вектор.

## [1] 2 4 6
## [1] -9.30  0.00  2.17 21.30

Задание 6

Создайте вектор, в котором будет три наименьших отрицательных простых числа в порядке возрастания.

## [1] -3 -2 -1
## [1] -3 -2 -1


Создание векторов при помощи seq()

Функция seq() создает последовательности с заданным шагом или заданной длины.

## [1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0

Если вы посмотрите в справку к seq(), то увидите, что в шаблоне ее вызова перечислены аргументы в определенном порядке: from, to, by и так далее.

В R можно вызывать функцию не только указывая ее аргументы с именами, но и просто в том порядке, в котором они следуют в шаблоне. Поэтому другой вариант кода даст тот же результат:

## [1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0

Так можно поступать лишь с элементарными функциями. Если вы делаете что-то сложное, лучше назовите аргументы по именам — ваш код будет легче читать.

Задание 7

Посмотрите в справку к функции seq() и выясните, как создавать последовательности заданной длины. Создайте последовательность от -1 до 1 из 9 элементов.

## [1] -1.00 -0.75 -0.50 -0.25  0.00  0.25  0.50  0.75  1.00


Векторы можно хранить в переменных для последующего использования

## [1] -4 -3 -2 -1  0  1  2  3  4
## [1] 100 200 300 400
## [1] 1.3 1.7 1.2 0.4

Задание 8

  • Создайте вектор nums, в котором сначала следуют все элементы вектора my_num, а затем все элементы вектора my_num_1.
  • Создайте вектор nums_2, в котором сначала идут элементыmy_num, а потомmy_num_2`.


ПривЕдение типов (маленькое и дружелюбное)

Посмотрите внимательно на вектор my_num, который мы только что создали.

## [1] 1.3 1.7 1.2 0.4

Произошло (без нашего ведома) приведение типов данных (от слова “приводить”). При объединении в один вектор данные должны были быть приведены к одному и тому же типу, поэтому целые числа превратились в дробные. И это хорошо, что не наоборот — так мы не потеряли точность.

Мы еще не раз столкнемся с приведением типов. К счастью, в большинстве случаев нас будет устраивать то, что R делает сам и нам почти никогда не придется делать приведение типов в явном виде.

Векторизованные операции

Со всеми элементами вектора можно разом делать одинаковые операции. Это называется “векторизованные операции”. Математические операции и многие функции векторизованы, это значит, что вам не придется перебирать элементы вектора, чтобы сделать с ними повторяющиеся действия. Посмотрим, как это выглядит на примере:

## [1] 1 2 3 4 5 6 7 8 9
## [1]  6  7  8  9 10 11 12 13 14
## [1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5
## [1] 2.0000000 1.0000000 0.6666667 0.5000000 0.4000000 0.3333333 0.2857143
## [8] 0.2500000 0.2222222

Адресация внутри векторов

При помощи оператора [], можно обратится к элементам вектора. В квадратных скобках вам нужно указать вектор из одного или нескольких индексов — порядковых номеров элементов.

Если вам нужен один элемент, все просто:

## [1] -4
## [1] 100
## [1] NA

А если вам нужно несколько элементов?

Вектор — одномерный объект. У его элементов только один порядковый номер (индекс). Поэтому при обращении к элементам вектора нужно указывать только одно число или один вектор с адресами, как мы это делали в предыдущих примерах. Но R выдаст ошибку, если при обращении к вектору, вы не создавали вектор, а просто перечислили номера элементов через запятую.

Если вам нужно несколько элементов, то их нужно передать квадратным скобкам в виде вектора.

## [1] -3 -1  1
## [1] -2 -1  0

Задание 9

Извлеките из вектора nums элементы:

  • с 10 по 13
  • 1, 3, и 5
  • с 1 по 3 и 13
## [1] 100 200 300 400
## [1] -4 -2  0
## [1]  -4  -3  -2 400


Задание 10

Что будет, если в квадратных скобках указать отрицательный индекс элемента?

  • -13
  • -1
  • -c(1:3, 13)

И что будет, если обратится к элементу с номером, больше, чем число элементов в векторе?

  • Например, с номером 42.


Встроенные константы в R

Встроенные константы в R: NA, NULL, NAN, Inf

  • NA - англ “not available”. Когда объект был, но его свойство не измерили или не записали.
  • NULL - пусто - просто ничего нет
  • NaN - “not a number”
  • Inf - “infinity” - бесконечность

Если попросили добыть из вектора номер элемента, которого там точно нет, то R выдаст NA, потому, что такого элемента нет.

Теперь посмотрим на встроенные константы в действии.

Создаем новый вектор с пропущенным значением для экспериментов.

Вот так он выглядит:

## [1]  1  3 NA  9  0 27

Что произойдет с NA?

## [1]  3  5 NA 11  2 29
## [1]  0  0 NA  0  0  0
## [1] Inf Inf  NA Inf NaN Inf

Но в последнем случае вы увидите

  • Inf при делении чисел на ноль
  • NaN при делении нуля на ноль

NaN получится, если взять корень из отрицательного числа

## Warning in sqrt(-1): NaNs produced
## [1] NaN

Некоторые типы данных в R

Числовые данные

Только что видели

Текстовые данные

Каждый текстовый элемент (говорят “строка” - string, character) должен быть окружен кавычками - двойными или одинарными.

## [1] "это текст"
## [1] "это тоже текст"
## [1] "2"

С обычным текстом нельзя работать как с числом, но некоторый текст может превращаться в число.

Можно принудительно превратить число в кавычках в числовые данные.

## [1] 2
## [1] 4

При этом нельзя превратить обычный текст в число

Текстовые значения можно объединять в векторы и работать с ними как обычно. Давайте попробуем поэкспериментировать.

Задание 11

Создайте вектор rainbow с названиями цветов радуги. Добудьте из этого вектора при помощи [] элементы 1 и 6.


Логические данные

## [1] TRUE
## [1] FALSE

Для ленивых - можно сокращать первыми заглавными буквами. Но лучше так не делать, чтобы читать программы было легче.

## [1]  TRUE FALSE

Для проверки условий используются операторы сравнения и сопоставления == < > <= >= %in%.

Логические операторы используются для объединения результатов нескольких проверок: И - &, ИЛИ - |, НЕ - !

## Help on topic 'Logic' was found in the following packages:
## 
##   Package               Library
##   base                  /usr/lib/R/library
##   methods               /usr/lib/R/library
## 
## 
## Using the first match ...

Давайте представим, что перед нами несколько чашек с чаем. В них разное число кусков сахара и разная температура. И чай в них черный или зеленый.

В векторах sugar, temp и tea информация об одних и тех же чашках в одинаковом порядке. Такие векторы мы назовем “сопряженные”.

##  [1]  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE
##  [1] FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
## [1] 6
## [1]  2  5  6  8  9 10

Теперь посмотрим на логические операторы.

##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

Важный логический оператор — отрицание ! (восклицательный знак).

## [1] FALSE
## [1] TRUE
##  [1] FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
##  [1]  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE

Задание 12

При помощи логических векторов ответьте на эти вопросы:

  • В каких чашках нет сахара?
  • В каких чашках холодный чай (меньше 40 градусов)?
  • В каких чашках 0, 3 или 5 кусков сахара?
  • В каких чашках нет сахара и чай горячий (больше 40 градусов)?
##  [1] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE
##  [1] FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
##  [1] FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE
##  [1] FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE


Логические векторы можно использовать в [], чтобы отобрать данные, соответствующие условию.

## [1] "B" "G" "B"
## [1] 22 35 47 55

Задание 13

При помощи логических векторов отберите нужные данные:

  • цвет чая, в котором нет сахара
  • температура чая, в котором три или больше кусков сахара
  • цвет чая, в котором 0, 3 или 5 кусков сахара


Факторы

Факторы - это способ хранения дискретных (=категориальных данных). Например, если вы поймали 10 улиток и посмотрели их цвет. У большого количества улиток небольшое счетное количество возможных цветов.

## [1] "r" "r" "r" "y" "y" "g" "g" "g" "g"

Но цвет “желтый” обозначает одно и то же для каждой из улиток. Поэтому в целях экономии места можно записать цвета этих улиток в виде вектора, в котором численным значениям будут сопоставлены “этикетки” (называются “уровни” - levels) - названия цветов. Мы можем создать “фактор” цвет улиток.

## [1] r r r y y g g g g
## Levels: g r y

уровни (levels) этого фактора

  • 1 - g,
  • 2 - r,
  • 3 - y

По умолчанию, R назначает порядок уровней по алфавиту. Можно изменить порядок (см. help("factor")). Нам это пригодится позже для работы с дискретными переменными.

Факторы особенно полезны, когда у вас дискретный признак записан числами. Например, вы записали цвет улиток номерами оттенков Pantone (это фантастические улитки, все их цвета из палитры C, поэтому мы записали их только числами).

Для R это просто числа, поэтому он простодушно может посчитать сумму этих чисел или даже разделить их на какое-то число. Хотя такие операции с цветами улиток не имеют смысла.

## [1] 10803
## [1]  242.5  242.5  242.5   51.0   51.0 1143.0 1143.0 1143.0 1143.0

Правильно было бы сказать R, что snails_pantone — это фактор, и там содержаться просто какие-то дискретные значения.

## [1] 485  485  485  102  102  2286 2286 2286 2286
## Levels: 102 485 2286

Арифметические операции с фактором вызовут ошибки и предупреждения — это как раз то, чего мы хотели.

Функции в R

Вы уже видели массу функций, их легко узнать по скобкам после ключевого слова. Познакомимся еще с несколькими и научимся писать пользовательские функции. Пользовательские функции позволяют автоматизировать повторяющиеся действия и делают код легко читаемым.

Вот наш вектор

##  [1]  -4  -3  -2  -1   0   1   2   3   4 100 200 300 400

Длину вектора можно вычислить при помощи функции length()

## [1] 13

Сумму элементов вектора при помощи функции sum()

## [1] 1000

Задание 14

Вычислите среднее значение для вектора nums. Вначале попробуйте сделать это “вручную” при помощи функций length() и sum(). Как вы думаете, как называется функция, которая может это сделать сразу?

## [1] 76.92308
## [1] 76.92308


Сумма не работает, если в векторе есть NA.

## [1]  1  3 NA  9  0 27
## [1] 6
## [1] NA

Чтобы узнать, почему и как это исправить - посмотрите в help("sum"). Выяснится, что у функции sum() есть аргумент na.rm, который по умолчанию принимает значение FALSE, то есть NA не учитываются при подсчете суммы.

Если мы передадим функции sum аргумент na.rm = TRUE, то получится правильная сумма

## [1] 40

Та же история с функцией mean

## [1] 8

Датафреймы

Датафрейм - один из способов хранения табличных данных в R,

Векторы одинаковой длины можно хранить вместе в виде таблицы.

##   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
## [1] "data.frame"
## 'data.frame':    9 obs. of  3 variables:
##  $ Length: int  1 2 3 4 5 6 7 8 9
##  $ Width : num  2 4 6 8 10 12 14 16 18
##  $ Colour: Factor w/ 2 levels "green","red": 1 1 1 1 2 2 2 2 2

Задание 15

Создайте из этих векторов датафрейм под названием Jedi с колонками name, homeworld и num_starships.


Навигация внутри датафреймов

У каждой ячейки в датафрейме есть координаты вида [строка, столбец]

## [1] green
## Levels: green red
##   Length Width Colour
## 2      2     4  green
## [1]  2  4  6  8 10 12 14 16 18
## [1]  2  4  6  8 10 12 14 16 18

Переменные можно извлечь при помощи оператора $ и имени переменной

## [1] 1 2 3 4 5 6 7 8 9
## [1]  2  4  6  8 10 12 14 16 18

Имена переменных можно использовать и внутри оператора []

## [1] 1 2 3 4 5 6 7 8 9
## [1]  2  4  6  8 10 12 14 16 18

Задание 16

Извлеките из датафрейма Jedi

  • третью строку
  • вектор имен персонажей
  • значение в первом столбце четвертой строки
##             name homeworld num_starships
## 3 Obi-Wan Kenobi   Stewjon             5
## [1] Luke Skywalker Darth Vader    Obi-Wan Kenobi Yoda          
## Levels: Darth Vader Luke Skywalker Obi-Wan Kenobi Yoda
## [1] Luke Skywalker Darth Vader    Obi-Wan Kenobi Yoda          
## Levels: Darth Vader Luke Skywalker Obi-Wan Kenobi Yoda
## [1] Luke Skywalker Darth Vader    Obi-Wan Kenobi Yoda          
## Levels: Darth Vader Luke Skywalker Obi-Wan Kenobi Yoda
## [1] <NA>
## Levels: Stewjon Tatooine
## [1] <NA>
## Levels: Stewjon Tatooine


Задание 17

Создайте датафрейм cups из созданных ранее векторов tea, temp, sugar. Пусть переменные в нем называются заглавными буквами: TEA, TEMP, SUGAR

При помощи [ ] извлеките из cups данные согласно заданию. Используйте ТОЛЬКО данные из датафрейма cups, а не исходные векторы:

  • Строки с чашками без сахара
  • Строки с чашками, где 0, 3 или 5 кусков сахара
  • Только данные о температуре и количестве сахара
  • Цвет чая, в котором нет сахара
  • Температура зеленого чая
##    TEA TEMP SUGAR
## 1    B   40     1
## 2    B   50     3
## 3    G   22     0
## 4    B   22     2
## 5    B   53     3
## 6    B   41     4
## 7    G   35     1
## 8    G   47     0
## 9    G   55     5
## 10   B   52     0
## [1] TEA   TEMP  SUGAR
## <0 rows> (or 0-length row.names)
##    TEA TEMP SUGAR
## 2    B   50     3
## 3    G   22     0
## 5    B   53     3
## 8    G   47     0
## 9    G   55     5
## 10   B   52     0
##    TEMP SUGAR
## 1    40     1
## 2    50     3
## 3    22     0
## 4    22     2
## 5    53     3
## 6    41     4
## 7    35     1
## 8    47     0
## 9    55     5
## 10   52     0
##    TEMP SUGAR
## 1    40     1
## 2    50     3
## 3    22     0
## 4    22     2
## 5    53     3
## 6    41     4
## 7    35     1
## 8    47     0
## 9    55     5
## 10   52     0
## [1] G G B
## Levels: B G
## [1] G G B
## Levels: B G
## [1] G G B
## Levels: B G
## [1] 22 35 47 55
## [1] 22 35 47 55
## [1] 22 35 47 55


Пакеты R и их установка.

В R похожие группы функций или функции для решения какой-то определенной задачи сгруппированы в пакеты. Часть пакетов у вас уже установлена по умолчанию вместе с базовой конфигурацией R. Какие-то нужные пакеты нам придется установить из репозитория на сайте CRAN или одном из его зеркал.

Выбираем в настройках источник для установки пакетов (это придется сделать только один раз). В меню Tools -> Global Options На вкладке Packages выбираем подходящее зеркало сайта CRAN (CRAN mirror). Мы рекомендуем чешские или немецкие зеркала, потому что российские часто барахлят.

Установка пакетов в систему делается один раз при помощи функции install.packages("имя_пакета"). Для установки пакетов с зеркала CRAN вы должны быть подключены к интернету. После установки пользоваться пакетами можно будет без подключения.

Для работы в этом курсе вам потребуются разные пакеты. Давайте установим некоторые из них и заодно изучим, как работает эта функция.

Не пугайтесь, вам напишут много текста. Главное, чтобы в нем не было слова ERROR.

Пакеты можно устанавливать по одному, как вы это видели только что, а можно сразу несколько (только в этом случае немного сложнее понять, если какой-то пакет не установился).

Самый простой способ проверить, установлен ли пакет — это пойти на вкладку Packages (в той же части окна RStudio, где Help) и набрать в поисковой строке название пакета.

Пакеты в систему придется установить один раз, но для работы с ними их придется каждый раз активировать (доставать из локальной библиотеки пакетов при помощи функции library()).

Как работать с пакетами мы поговорим в следующий раз.