R: краткий словарик

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

Функции

Работа в R строится на использовании функций. Но что такое функция? Функция – это маленькая программа, представляющая из себя последовательность простых (или не очень) операций, которые проводятся над каким-то объектом, который мы отдали функции на обработку. Этот объект называется аргументом. Например, есть функция, которая извлекает квадратный корень из некоторого числа. Число будет аргументом функции (совсем как в математике). Функция может иметь несколько аргументов, указывающих не только на то, с каким объектом нужно проводить операции, но и как их проводить.

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

?sqrt

Пакеты

Для того, чтобы пользоваться всеми – многогранными – возможностями R, вам потребуется обращаться к внешним пакетам. Пакет в R – это группа функций, объединенных выполнением схожих задач. Например, пакет foreign позволяет загружать в R файлы данных различных расширений (например, из файлы данных из пакетов SPSS или Stata) и сохранять данные в файлы с этими расширениями.

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

install.packages("foreign")

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

После того, как вы установили программу, вы захотите ее открыть. Также нужно открывать и пакеты в R перед их использованием каждый раз, когда вы запускаете R. Это делается так – теперь название пакета прописывается без кавычек:

library(foreign)

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

Рабочая директория

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

getwd() 

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

setwd("C:/Users/student/Desktop/pr01")

Там не менее, вы можете открыть файл из любой папки и записать файл в любую папку, просто прописав полный путь к ней.

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

Некоторые математические функции

10+320
## [1] 330
10*320
## [1] 3200

Функция квадратного корня:

sqrt(3200)
## [1] 56.56854

Функция модуля:

abs(-16)
## [1] 16

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

round(2/3)
## [1] 1

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

round(2/3, 4)
## [1] 0.6667

Обратите внимание, что в R, в отличие от Excel, целая часть от дробной отделяется точкой.

Экспоненциальная запись числа

В ряде резлуьтатов в будущем нам будет встречаться так называемая экспоненциальная запись чисел. Она используется для удобного отображения очень больших или очень маленьких чисел через произведение \(a\times 10^b\), где a – любое число, по модулю не меньшее 1, но меньшее 10. Например, мы можем представить миллион как произведение \(1\times 10^6\).

Давайте посмотрим на очень большое число, возведя число 16 в степень 16:

16^16
## [1] 1.844674e+19

R обозначет умножение на 10 в некоторой степени как e.

Теперь очень маленькое число. Обратите внимание на знак после e:

1/16^16
## [1] 5.421011e-20

Вероятности известных распределений

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

Для этого используется функция pnorm(), имеющая три аргумента: q – значение (или значения) случайной величины, для которых мы ищем вероятности; mean – математическое ожидание; sd – стандартное отклонение; lower.tail – поиск вероятности \(P(X<x)\). По дефолту (то есть, если не прописывать иное) аргументы функции принимают следующие значения: pnorm(q, mean=0, sd=1, lower.tail=TRUE).

Рассчитаем \(F(1)=P(Z<1)\):

pnorm(1)
## [1] 0.8413447

Эта же функция позволяет рассчитать \(P(Z>1)\). Для этого нужно прописать аргумент lower.tail=FALSE, тем самым выбрав площадь под графиком функции плотности стандартного нормального распределения, которая рассматриваемого искомого значения.

pnorm(1, lower.tail = FALSE)
## [1] 0.1586553

Мы можем работать не только со стандартным нормальным распределением:

pnorm(5, mean=7, sd=3)
## [1] 0.2524925

Объекты R

Работа с R выстраивается через работу с объектами, в которые вы сохраняете результаты ваших вычислений или любую другую необходимую информацию, и к которым можете впоследствии обращаться. Удобство R заключается в том, что вы, например, можете работать одновременно с несколькими таблицами, полученными из различных источников (тогда как, чтобы открыть новый файл в Excel, вам требуется запустить новое окно программы).

Начнем с самых простых объектов, содержащих один элемент. Давайте сохраним в объект pr_left (от probability) вероятность того, что \(Z<1\). Чтобы это сделать, нужно воспользоваться оператором присваивания <-. Код читается так: нужно сохранить вероятность, рассчитанную функцией pnorm(), в объект pr_left.

pr_left <- pnorm(1)

Создадим еще один объект, куда запишем вероятность того, что \(Z>1\).

pr_right <- pnorm(1, lower.tail = FALSE)

Примечание. Названия объектов могут быть любыми (но не могут содержать пробелов), но традиционно они должны быть удобны в работе: короткими и отражающими содержание. Например, базы данных часто называют как df или data.

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

Что, если мы хотим сравнить эти два значения? Для этого в R существуют логические операторы ==, !=, >, <, >= (больше или равно), <= (меньше или равно). Эти операторы важно знать, чтобы в дальнейшем уметь проводить отбор наблюдений по некоторым условиям.

Результатом сравнений будет логические значения TRUE или FALSE:

pr_left == pr_right
## [1] FALSE

Действительно ли эти вероятности не равны?

pr_left != pr_right
## [1] TRUE

Типы данных

В R существуют несколько базовых типов данных:

  1. logical – логические. Мы уже сталкивались с ними при использовании логических операторов. Принимают значения TRUE или FALSE.
  2. numeric – числовые, включая дробные значения.
  3. character – текстовые. В прикладном анализе вы столкнетесь с еще одним типом данных:
  4. factor – факторные или категориальные. Они представляют собой качественную текстовую информацию (например, его пол), закодированную в цифрах. При этом, каждому числовому значению сопоставляется текстовая метка – лейбл.

Мы можем проверять, к какому типу данных относятся наши объекты:

is.numeric(pr_left)
## [1] TRUE
is.character(pr_left)
## [1] FALSE
is.logical(pr_left)
## [1] FALSE

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

as.character(pr_left)
## [1] "0.841344746068543"

Можно узнать тип объекта:

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

Векторы

Вектором называется набор объектов, имеющих одинаковый тип. Векторы в R создаются через структуру c(). Создадим вектор имен некоторых героев сериала «Твин Пикс»:

damn_good_coffee <- c("Laura", "Harry", "Donna", "Dale", "Audrie")

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

damn_good_coffee[3]
## [1] "Donna"

Можно вызвать элементы, расположенные рядом. Например, мы хотим вызвать 2, 3 и 4 имя:

damn_good_coffee[2:4]
## [1] "Harry" "Donna" "Dale"

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

damn_good_coffee[c(1,5)]
## [1] "Laura"  "Audrie"

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

Функция lenght() считает количество элементов в векторе:

length(names)
## [1] 1

Часто мы хотим узнать номер элемента внутри вектора, зная его значение. Для этого существует функция which(), где аргумент vector == value нужно читать как «какой/-ие из элементов вектора vector принимают значение value?»:

which(damn_good_coffee == "Dale")
## [1] 4

Векторы могут быть и чаще всего будут числовыми. Создадим вектор, принимающий целые значения от 1 до 20:

pineapple <- c(1:20)
pineapple
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

Над векторами можно производить математические операции, которые будут осуществляться поэлементно. Например, в строке ниже каждый из элементов вектора pineapple будет разделен на 10.

pineapple/10
##  [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7
## [18] 1.8 1.9 2.0

Можно отбрать элементы вектора на основании некоторых условий. Например:

pineapple[pineapple>=15 & pineapple <=18]
## [1] 15 16 17 18

Вот так мы можем исключить элемент, равный 15, из вектора:

pineapple[pineapple!=15]
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 16 17 18 19 20

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

pineapple[10]
## [1] 10
pineapple[10] <- 1000000

С помощью функции replace() можно заменить сразу много элементов, удовлетворяющих некоторому условию. Если вам потребуется преобразованный вектор, не забудьте сохранить его в новый объект:

avocado <- replace(pineapple, # то, где заменяем
        pineapple <= 8, # условие замены
        -1) # на что заменяем

avocado
##  [1]      -1      -1      -1      -1      -1      -1      -1      -1
##  [9]       9 1000000      11      12      13      14      15      16
## [17]      17      18      19      20

Другой способ произвести замену многих элементов, удовлетворяющих условию:

avocado[avocado > 9] = 1 
avocado
##  [1] -1 -1 -1 -1 -1 -1 -1 -1  9  1  1  1  1  1  1  1  1  1  1  1

Таблица

Что такое база данных? Это таблица, где каждая из строк содержит описания одного и того же наблюдения: например, респондента, региона или страны. В столбцах в этой таблице содержатся переменные – список измерений одного и того же признака, собранного для всех наблюдений в базе данных: например, рост и возраст респондента, средняя зарплата в регионе или количество политических партий в стране.

На семинаре мы провели мини-исследование, в котором студенты ответили на несколько вопросов про их рост, баллы ЕГЭ по биологии и математике, любимый предмет в школе, а также оценили на глазок длину представленного отрезка и угол. Мы случайно отобрали 7 анкет и занесли полученные результаты в векторы ответов на один и тот же вопрос. Они потребуются нам, чтобы собрать нашу первую базу данных. Векторы будут соответствовать столбцам, а номера элементов в векторе – строкам.

Рост:

height <- c(170, 169, 164, 163, 171, 161, 169.5)

Балл ЕГЭ по математике. У нас было 2 пропущенных значения. Эти пропущенные значения нельзя просто выкидывать. Нужно закодировать, что ответ на вопрос не был дан, через NA.

math_score <- c(76, 67, NA, 74, 78, NA, 72)

Балл ЕГЭ по биологии.

bio_score <- c(90, 79, NA, 77, 88, 66, 87)

Любимый предмет. Респонденту нужно было выбрать один ответ из 5 предложенных вариантов:

  1. Математика;
  2. Биология;
  3. Русский язык;
  4. Иностранный язык;
  5. Ни один из вышеперечисленных предметов.

В вектор вносим код ответа:

subject <- c(2, 2, 5, 4, 2, 4, 2)

Пол (1 – девушка, 2 – молодой человек):

sex <- c(1, 1, NA, 1, 1, 1, 1)

Длина предложенного отрезка:

length <- c(20, 40, 30, 25, 25, 20, 25)

Предложенный угол:

angle <- c(20, 30, 30, 30, 22.5, 30, 37.5)

Обратите внимание: для корректного создания таблицы вам нужно, чтобы длина всех векторов была одинаковая.

Создадим нашу первую базу данных, используя функцию data.frame(). В аргументе через запятую вы присваиваете через оператор = названию колонки в таблице соответствующий вектор. Названия вы можете выбрать любые.

banana <- data.frame(height=height, 
                     math=math_score, 
                     bio=bio_score, 
                     subject=subject,
                     gender=sex,
                     length=length,
                     angle=angle)
banana
##   height math bio subject gender length angle
## 1  170.0   76  90       2      1     20  20.0
## 2  169.0   67  79       2      1     40  30.0
## 3  164.0   NA  NA       5     NA     30  30.0
## 4  163.0   74  77       4      1     25  30.0
## 5  171.0   78  88       2      1     25  22.5
## 6  161.0   NA  66       4      1     20  30.0
## 7  169.5   72  87       2      1     25  37.5

Чтобы посмотреть на получившуюся базу данных в отдельном окне, можно воспользоваться функцией View(). Обратите внимание, что функция пишется с заглавной буквы, а R чувствителен к регистру. Если вы напишете ее с маленькой буквы, R не поймет.

View(banana)

Отбор наблюдений

Один из важных навыков работы с данными – отбор наблюдений, удовлетворяющих некоторому условию. Например, среди всех ответов участников эксперимента вы хотите поработать только с ответами девушек. Отбор наблюдений производится с помощью команды subset(), где первым аргументом будет ваша таблица с данными, а вторым – требуемое условие.

subset(banana, height > 165)
##   height math bio subject gender length angle
## 1  170.0   76  90       2      1     20  20.0
## 2  169.0   67  79       2      1     40  30.0
## 5  171.0   78  88       2      1     25  22.5
## 7  169.5   72  87       2      1     25  37.5
subset(banana, subject == 5)
##   height math bio subject gender length angle
## 3    164   NA  NA       5     NA     30    30

Можно задавать сложные условия, используя логическое и: & (студенты, чей рост больше 165 см, и указанная ими длина отрезка превышает 25 см).

subset(banana, height > 165 & length > 25)
##   height math bio subject gender length angle
## 2    169   67  79       2      1     40    30

А можно логическое или: | (студенты, чей рост больше 165 см или студенты, чья указанная длина отрезка превышает 25 см).

subset(banana, height > 165 | length > 25)
##   height math bio subject gender length angle
## 1  170.0   76  90       2      1     20  20.0
## 2  169.0   67  79       2      1     40  30.0
## 3  164.0   NA  NA       5     NA     30  30.0
## 5  171.0   78  88       2      1     25  22.5
## 7  169.5   72  87       2      1     25  37.5

Вашу базу данных вы можете сохранить в новый файл, чтобы потом смочь к нему вернуться. Запишем файл в файл расширения .csv, который может быть открыть в Excel. Файл сохранится в ту папку, которую вы указали как рабочую директорию в начале занятия.

write.csv2(banana, "banana.csv")

Вместо заключения