2 Introduction to R

2.1 Install R & Rstudio

You need to download and install R first.

  • R
    • Windows, find a big button Download R (version number) for Windows.
    • Mac, if your Mac computer is less than 5 years old, you can just download and install the last version of .pkg. If your Mac is older than that, find the appropriate version on the same page depending on your version of macOS.
    • на Linux, or you can add mirror and download R from the terminal:
sudo apt-get install r-cran-base

We use this version of R for this book:

sessionInfo()$R.version$version.string
## [1] "R version 4.0.2 (2020-06-22)"

After you download and install R on your system, you need to download and install RStudio:

If you cannot install R and RStudio for whatever reason, you can run RStudio in a cloud using web-browser:

The first and very logical question: why do we install both R and RStudio? In brief, R is a programming language, but RStudio is an Integrated Development Environment (IDE) – a program that makes working with this programming language easy and comfortable.

RStudio is not the only IDE for R, but it is definetily the best one. Almost everyone use it for R and you don’t need to spend time to find the better solution. If you are used to use Jupyter Notebook, you will learn to use wonderful RMarkdown (that was used to write this online-book) instead and we learn Rmarkdown later.

2.2 Знакомство с RStudio

Так, давайте взглянем на то, что нам тут открылось:

В первую очередь нас интересуют два окна: 1 - Code Editor (окно для написания скриптов)1 и 2 - R Console (консоль). Здесь можно писать команды и запускать их. При этом работа в консоли и работа со скриптом немного различается.

В 2 - R Console вы пишите команду и запускаете ее нажиманием Enter. Иногда после запуска команды появляется какой-то результат. Если нажимать стрелку вверх на клавиатуре, то можно выводить в консоль предыдущие команды. Это очень удобно для запуска предыдущих команд с небольшими изменениями.

В 1 - Code Editor для запуска команды вы должны выделить ее и нажать Ctrl + Enter (Cmd + Enter на macOS). Если не нажать эту комбинацию клавиш, то команда не запустится. Можно выделить и запустить сразу несколько команд или даже все команды скрипта. Все команды скрипта можно выделить с помощью сочетания клавиш Ctrl + A на Windows и Linux, Cmd + A на macOS.2 Как только вы запустите команду (или несколько команд), соответствующие строчки кода появятся в 2 - R Console, как будто бы вы запускали их прямо там.

Обычно в консоли удобно что-то писать, чтобы быстро что-то посчитать. Скрипты удобнее при работе с длинными командами и как способ сохранения написанного кода для дальнейшей работы. Для сохранения скрипта нажмите File - Save As.... R скрипты сохраняются с разрешением .R, но по своей сути это просто текстовые файлы, которые можно открыть и модифицировать в любом текстовом редакторе а-ля “Блокнот.”

3 - Workspace and History — здесь можно увидеть переменные. Это поле будет автоматически обновляться по мере того, как Вы будете запускать строчки кода и создавать новые переменные. Еще там есть вкладка с историей всех команд, которые были запущены.

4 - Plots and files. Здесь есть очень много всего. Во-первых, небольшой файловый менеджер, во-вторых, там будут появляться графики, когда вы будете их рисовать. Там же есть вкладка с вашими пакетами (Packages) и Help по функциям. Но об этом потом.

2.3 R как калькулятор

R — полноценный язык программирования, который позволяет решать широкий спектр задач. Но в первую очередь R используется для анализа данных и статистических вычислений. Тем не менее, многими R до сих пор воспринимается как просто продвинутый калькулятор. Ну что ж, калькулятор, так калькулятор.

Давайте начнем с самого простого и попробуем использовать R как калькулятор с помощью арифметических операторов +, -, *, /, ^ (степень), () и т.д.

Просто запускайте в консоли пока не надоест:

40+2
## [1] 42
3-2
## [1] 1
5*6
## [1] 30
99/9 #деление
## [1] 11
2^3 #степень
## [1] 8
13 %/% 3 #целочисленное деление
## [1] 4
13 %% 3 #остаток от деления
## [1] 1

Попробуйте самостоятельно посчитать что-нибудь с разными числами.

Ничего сложного, верно? Вводим выражение и получаем результат.

Вы могли заметить, что некоторые команды у меня заканчиваются знаком решетки (#). Все, что написано в строчке после # игнорируется R при выполнении команды. Написанные команды в скрипте рекомендуется сопровождать комментариями, которые будут объяснять вам же в будущем (или кому-то еще), что конкретно происходит в соответствующем куске кода.3 Кроме того, комментарии можно использовать в тех случаях, когда вы хотите написать кусок кода по-другому, не стирая полностью предыдущий код: достаточно “закомментить” нужные строчки - поставить # в начало каждой строки, которую вы хотите переписать. Для этого есть специальное сочетание горячих клавиш: Ctrl + Shift + C (Cmd + Shift + C на macOS) — во всех выделенных строчках будет написан # в начале.

Согласно данным навязчивых рекламных баннеров в интернете, только 14% россиян могут справиться с этим примером:

2 + 2 * 2
## [1] 6

На самом деле, разные языки программирования ведут себя по-разному в таких ситуациях, поэтому ответ 6 (сначала умножаем, потом складываем) не так очевиден.

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

(2+2)*2
## [1] 8

Если Вы не уверены в том, какие операторы имеют приоритет, то используйте скобочки, чтобы точно обозначить, в каком порядке нужно производить операции. Или же смотрите на таблицу приоритета операторов с помощью команды ?Syntax.

2.4 Функции

Давайте теперь извлечем корень из какого-нибудь числа. В принципе, тем, кто помнит школьный курс математики, возведения в степень вполне достаточно:

16 ^ 0.5
## [1] 4

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

Вот, например, функция для корня:

sqrt(16)
## [1] 4

R — case-sensitive язык, т.е. регистр важен. SQRT(16) не будет работать.

А вот так выглядит функция логарифма:

log(8)
## [1] 2.079442

Так, вроде бы все нормально, но… Если Вы еще что-то помните из школьной математики, то должны понимать, что что-то здесь не так.

Здесь не хватает основания логарифма!

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

То есть у логарифма 8 по основанию 2 будет значение 3:

\(\log_2 8 = 3\)

То есть если возвести 2 в степень 3 у нас будет 8:

\(2^3 = 8\)

Только наша функция считает все как-то не так.

Чтобы понять, что происходит, нам нужно залезть в хэлп этой функции:

?log

Справа внизу в RStudio появится вот такое окно:

Действительно, у этой функции есть еще аргумент base =. По умолчанию он равен числу Эйлера (2.7182818…), т.е. функция считает натуральный логарифм. В большинстве функций R есть какой-то основной инпут — данные в том или ином формате, а есть и дополнительные параметры, которые можно прописывать вручную, если параметры по умолчанию вас не устраивают.

log(x = 8, base = 2)
## [1] 3

…или просто (если Вы уверены в порядке переменных):

log(8,2)
## [1] 3

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

log(8, sqrt(4))
## [1] 3

Если эксплицитно писать имена аргументов, то их порядок в функции не важен:

log(base = 2, x = 8)
## [1] 3

А еще можно писать имена аргументов не полностью, если они не совпадают с другими:

log(b = 2, x = 8)
## [1] 3

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

Арифметические знаки, которые мы использовали: +,-,/,^ и т.д. называются операторами и на самом деле тоже являются функциями:

'+'(3,4)
## [1] 7

2.5 В любой непонятной ситуации — гуглите

Если вдруг вы не знаете, что искать в хэлпе, или хэлпа попросту недостаточно, то… гуглите!

Нет ничего постыдного в том, чтобы гуглить решения проблем. Это абсолютно нормально. Используйте силу интернета во благо и да помогут вам Stackoverflow4 и бесчисленные R-туториалы!

Главное, помните: загуглить работающий ответ всегда недостаточно. Надо понять, как и почему решение работает. Иначе что-то обязательно пойдет не так.

Кроме того, правильно загуглить проблему — не так уж и просто.

Короче говоря: гуглить — хорошо, бездумно копировать чужие решения — плохо.

2.6 Переменные

Важная штука в программировании на практически любом языке — возможность сохранять значения в переменных. В R это обычно делается с помощью вот этих символов: <- (но можно использовать и обычное =, хотя это не очень принято). Для этого есть удобное сочетание клавиш: нажмите одновременно Alt + - (или option + - на macOS).

Заметьте, при присвоении результат вычисления не выводится в консоль! Если опустить детали, то обычно результат выполнения комманды либо выводится в консоль, либо записывается в переменную.

a <- 2
a
## [1] 2

Справа от <- находится значение, которое вы хотите сохранить, или же какое-то выражение, результат которого вы хотите сохранить в эту переменную5:

Слева от <- находится название будущей переменной. Название переменных может быть самым разным. Есть несколько ограничений для синтаксически валидных имен переменных: они должны включать в себя буквы, цифры, . или _, начинаться на букву (или точку, за которой не будет следовать цифра), не должны совпадать с коротким списком зарезервированных слов. Короче говоря, название не должно включать в себя пробелы и большинство других знаков.

Нельзя: - new variable - _new_variable - .1var - v-r

Можно: - new_variable - .new.variable - var_2

Обязательно делайте названия переменных осмысленными! Старайтесь делать при этом их понятными и короткими, это сохранит вам очень много времени, когда вы (или кто-то еще) будете пытаться разобраться в написанном ранее коде. Если название все-таки получается длинным и состоящим из нескольких слов, то лучше всего использовать нижнее подчеркивание в качестве разделителя: some_variable6.

После присвоения переменная появляется во вкладке Environment в RStudio:

Можно использовать переменные в функциях и просто вычислениях:

b <- a ^ a + a * a
b
## [1] 8
log(b, a)
## [1] 3

2.7 Логические операторы

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

a == b
## [1] FALSE

Заметьте, что сравнивая две переменные мы используем два знака равно ==, а не один =. Иначе это будет означать присвоение.

a = b
a
## [1] 8

Теперь Вы сможете понять комикс про восстание роботов на следующей странице (пусть он и совсем про другой язык программирования)

Этот комикс объясняет, как важно не путать присваивание и сравнение (хотя я иногда путаю до сих пор =( ).

Иногда нам нужно проверить на неравенство:

a <- 2
b <- 3

a == b
## [1] FALSE
a != b
## [1] TRUE

Восклицательный язык в программировании вообще и в R в частности стандартно означает отрицание.

Еще мы можем сравнивать на больше/меньше:

a > b
## [1] FALSE
a < b
## [1] TRUE
a >= b
## [1] FALSE
a <= b
## [1] TRUE

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

##Типы данных {#data_types}

До этого момента мы работали только с числами (numeric):

class(a)
## [1] "numeric"

На самом деле, в R три типа numeric: integer (целые), double (дробные), complex (комплексные числа)7. R сам будет конвертировать числа в нужный тип numeric при необходимости, поэтому этим можно не заморачиваться.

Если же все-таки нужно задать конкретный тип числа эксплицитно, то можно воспользоваться функциями as.integer(), as.double() и as.complex(). Кроме того, при создании числа можно поставить в конце L, чтобы обозначить число как integer:

is.integer(5)
## [1] FALSE
is.integer(5L)
## [1] TRUE

Про double есть еще один маленький секрет. Дело в том, что дробные числа хранятся в R как числа с плавающей запятой двойной точности. Дробные числа в компьютере могут быть записаны только с определенной степенью точности, поэтому иногда встречаются вот такие вот ситуации:

sqrt(2)^2 == 2
## [1] FALSE

Это довольно стандартная ситуация, характерная не только для R. Чтобы ее избежать, можно воспользоваться функцией all.equal():

all.equal(sqrt(2)^2, 2)
## [1] TRUE

Теперь нам нужно ознакомиться с двумя другими важными типами данных в R:

  1. Строковые (character) данные: набор букв, цифр и символов, которые должны выделяться кавычками.
s <- "Всем привет!"
s
## [1] "Всем привет!"
class(s)
## [1] "character"

Можно использовать как ", так и ' (что удобно, когда строчка внутри уже содержит какие-то кавычки).

"Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn"
## [1] "Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn"
  1. Логические (logical) данные: просто TRUE или FALSE.
t1 <- TRUE
f1 <- FALSE

t1
## [1] TRUE
f1
## [1] FALSE

Вообще, можно еще писать T и F (но не True и False!)

t2 <- T
f2 <- F

Это дурная практика, так как R защищает от перезаписи переменные TRUE и FALSE, но не защищает от этого T и F.

TRUE <- FALSE
## Error in TRUE <- FALSE: неправильная (do_set) левая сторона в присвоении
TRUE
## [1] TRUE
T <- FALSE
T
## [1] FALSE

Функция rm() позволяет удалить ненужную переменную:

rm(T)

Мы уже встречались с логическими значениями при сравнении двух числовых переменных. Теперь вы можете догадаться, что результаты сравнения, например, числовых или строковых переменных, можно тоже сохранять в переменные!

comparison <- a == b
comparison
## [1] FALSE

Это нам очень понадобится, когда мы будем работать с реальными данными: нам нужно будет постоянно вытаскивать какие-то данные из датасета, что как раз и построено на игре со сравнением переменных.
Чтобы этим хорошо уметь пользоваться, нам нужно еще освоить как работать с логическими операторами. Про один мы немного уже говорили — это логическое НЕ (!). ! превращает TRUE в FALSE, а FALSE в TRUE:

t1
## [1] TRUE
!t1
## [1] FALSE
!!t1 #Двойное отрицание!
## [1] TRUE

Еще есть логическое И (выдаст TRUE только в том случае если обе переменные TRUE):

t1 & t2
## [1] TRUE
t1 & f1
## [1] FALSE

А еще логическое ИЛИ (выдаст TRUE в случае если хотя бы одна из переменных TRUE):

t1 | f1
## [1] TRUE
f1 | f2
## [1] FALSE

Если кому-то вдруг понадобится другое ИЛИ (строгое ЛИБО) — есть функция xor(), принимающая два аргумента и возвращая TRUE только в том случае, если ровно один из двух аргументов равен TRUE.

Итак, мы только что разобрались с самой занудной (хотя и важной) частью - с основными типа данных в R и как с ними работать8. Пора переходить к чему-то более интересному и специфическому для R. Вперед к ВЕКТОРАМ!


  1. При первом запуске RStudio вы не увидите это окно. Для того, чтобы оно появилось, нужно нажать File - New File - R Script.↩︎

  2. В RStudio есть много удобных сочетаний горячих клавиш. Чтобы посмотреть их все, нажмите Help - Keyboard Shortcuts Help.↩︎

  3. Во время написания кода вам может казаться понятным то, что вы написали, но при возвращении к коду через некоторое время вы уже не будете этого помнить. Старайтесь писать комментарии как можно чаще!↩︎

  4. Stackoverflow — это сайт с вопросами и ответами. Эдакий аналог Quora, The Question, ну или Ответы Mail.ru в мире программирования.↩︎

  5. Есть еще оператор ->, который позволяет присваивать значения слева направо, но так делать не рекомендуется, хотя это бывает довольно удобным.↩︎

  6. Еще иногда используются большие буквы SomeVariable, но это плохо читается, а иногда — точка, но это тоже не рекомендуется.↩︎

  7. Комплексные числа в R пишутся так: complexnumber <- 2+2i. i здесь - это та самая мнимая единица, которая является квадратным корнем из -1.↩︎

  8. Кроме описанных пяти типов данных (integer, double, complex, character и logical) есть еще и шестой — это raw, сырая последовательность байтов, но нам она не понадобится.↩︎