Найти тему
Nuances of programming

R - язык для статистической обработки данных. Часть 2/3

Оглавление

Источник: Nuances of Programming

Часть 1, Часть 2

Предыдущую часть мы закончили темой векторов, а в этой — переходим к матрицам. 

9. Что такое матрица?

Матрица, как структура данных, тоже часто встречается в R. 

Её можно рассматривать как расширение понятия вектора. У матрицы может быть множество строчек и столбцов. Все элементы матрицы должны иметь один тип данных.

Чтобы создать матрицу, пользуйтесь конструктором matrix(), а функции nrow и ncol пригодятся вам, чтобы определить количество строк и столбцов соответственно:

x <- matrix(nrow=4, ncol=4)

Так получается матричная переменная под названием x с 4-мя строками и 4-мя столбцами. Вектор можно трансформировать в матрицу, используя для этого конструктор matrix. Результирующая матрица будет заполняться по столбцам:

vector <- c(1, 2, 3)
x <- matrix(vector)
print(x)

Так получится матрица с одним столбцом и тремя строками (по одной для каждого элемента):

[,1]
[1,] 1
[2,] 2
[3,] 3

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

vector <- c(1, 2, 3, 4)
x <- matrix(vector, nrow=2, ncol=2, byrow=TRUE)
print(x)

Этот код создаёт матрицу с 2-мя столбцами и строчками. Заполняется матрица построчно.

[,1] [,2]
[1,] 1 2
[2,] 3 4

10. Что такое списки и факторы?

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

Списки

Списки — это очень важная структура данных в R. Чтобы создать список, пользуйтесь конструктором list():

my_list <- list("hello", 1234, FALSE)

Эта строчка кода иллюстрирует то, как создаётся список из трёх элементов с разными типами данных.

Мы можем получить доступ к любому элементу при помощи указателя. Например, так:

item_one = my_list[1]

Этот код в результате напишет “hello”.

Ещё мы можем назвать каждый элемент. К примеру, так:

Факторы

Факторы — это категориальные данные. Например: “да”, “нет” или “мужской”, “женский”, или “красный”, “синий”, “зелёный” и т.д.

Тип данных “фактор” можно использовать для представления факторного множества данных: 

my_factor = factor(c(TRUE, FALSE, TRUE))
print(my_factor)

Факторы также можно упорядочить (отсортировать):

my_factor = factor(c(TRUE, FALSE, TRUE), levels = c(TRUE, FALSE))
print(my_factor)

А ещё можем вывести факторы в формате таблицы:

my_factor = factor(c(TRUE, FALSE, TRUE), levels = c(TRUE, FALSE))
print(table(my_factor))

Это даст следующий результат:

TRUE FALSE
2 1

А сейчас давайте разберёмся с вопросами, связанными со статистикой.

11. Что такое датафреймы?

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

Чтобы создать датафрейм из 2-х столбцов и 5-ти строк, напишите следующее:

12. Различные логические операции в R

В этом разделе рассмотрим общепринятые операторы.

OR (или): первое | второе

Этот оператор проверяет, верно ли первое, или второе. Это дизъюнкция.

AND (и): первое & второе

Этот оператор проверяет, верно ли первое и второе. Это называется конъюнкция. 

NOT: !input

Этот оператор возвращает true, если было введено false. И наоборот. Операцию ещё называют инверсией.

Также можем пользоваться операторами:

< меньше, чем
<= меньше или равно;
=> больше или равно;
> больше, чем;
isTRUE(input) верно для вводимого;и другие.

13. Функции и область действия переменных в R

Иногда нам нужно, чтобы код решал не одну, а сразу комплекс задач. Эти задачи можно группировать в формате функций. А функции — это очень важные объекты в R.

В функцию можно передавать аргументы, а она может возвращать объект. 

В установленном пакете R есть определенное количество встроенных функций, в том числе: length(), mean() и т.д.

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

У функции есть имя. Оно хранится в окружении R. В теле функции находятся её операторы. 

Функция может возвращать значение и может принимать ряд аргументов (второе опционально).

Чтобы создать функцию, нам нужно написать следующее:

К примеру, мы можем создать функцию, которая берёт два целых числа и возвращает их сумму:

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

z <- my_function(1,2)
print(z)

Так на выходе получим 3.

Ещё мы можем установить значения по умолчанию для аргумента таким образом, чтобы оно было использовано в случае, когда значение аргументу не присвоено:

Значение по умолчанию y — 2. Так что мы можем вызвать функцию без присвоения значения y.

Запомните ключевое: используйте фигурные скобки {…}.

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

Предположим, что нужно создать функцию, которая принимает следующие аргументы: Mode (режим), x и y.

  • Если значение Mode равно True (истинно), то складываем x и y.
  • Если Mode False (ложное), то мы производим операцию вычитания между x и y.

Чтобы вызвать функцию сложения x и y, можем сделать так:

output <- my_function(TRUE, 1, 5)
print(output)

Это выведет 6.

Разберём код ниже. В частности, посмотрим, где наше print(z):

Ключевой момент в том, что z выводится после закрытия скобок. 

Будет ли переменная z доступна здесь? Это подводит нас к теме области действия в функциях.

Функция может быть объявлена внутри другой функции:

В примере выше some_func и another_func — это две функции. another_func объявляется внутри функции some_func. В результате another_func() является частной по отношению к some_func(). Следовательно она недоступна внешнему миру.

Если я выполню функцию another_func() снаружи функции some_func, как это показано ниже:

another_func()

Мы получим ошибку:

Error in another_func() : could not find function “another_func”

Ошибка в функции another_func() : невозможно найти функцию “another_func”.

С другой же стороны, мы можем выполнить another_func() внутри some_func() и она сработает именно так, как и ожидалось. 

Теперь рассмотрим этот код, чтобы понять, как работает область действия в R.

  • Функция some_func_variable доступна и для функции some_func, и another_func.
  • another_func_variable доступна только для функции another_func.

Выполнение этого кода приведёт к возникновению исключения в R-Studio:

> some_func()
[1] “DEF”
Error in print(“outside another func” + another_func_variable) :
object ‘another_func_variable’ not found

Это значит примерно следующее: ошибка при выводе, объект ‘another_func_variable’ не обнаружен. 

Как говорится в сообщении об ошибке, another_func_variable не обнаружена. Мы можем увидеть, что было выведено DEF, а это было значение, которое присвоили переменной some_func_variable.

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

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

my_func <- function(a, b, ...)
{
print(c)
}my_func(a=1,b=2,c=3)

14. Циклы в R

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

Циклы for

Иногда нам бывает нужно проитерировать элементы из множества. Синтаксис будет следующим: 

for (i in some_collection) {
print(i)
}

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

Ещё мы можем написать цикл для своего множества при помощи функции seq_along(). Она обрабатывает множество и генерирует последовательность целых чисел. 

Циклы while

Иногда нам нужен цикл, который выполняется, пока условие верно. А когда условие становится ложным, мы выходим из цикла.

Мы можем пользоваться циклом while, чтобы получить необходимую функциональность. 

В коде ниже мы устанавливаем значения: x = 3, а z = 0. Впоследствии мы увеличиваем значение z на 1 каждый раз, пока значение z равно или больше, чем x

If Else (опционально)

If Then Else часто используется в программировании.

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

Также можем ввести опциональное else:

Repeat

Если мы хотим повторить последовательность операторов неизвестное количество раз (например, пока условие выполняется или пользователь продолжает вводить значения), тогда мы можем повторять/прерывать операторы. Команда break заканчивает итерацию.

Если нам нужно пропустить итерацию, то мы можем воспользоватся следующим оператором:

15. Чтение и запись внешних данных в R

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

Читаем файл эксель

В результате отобразятся верхние строки:

Сниппет показывает содержимое Excel-файла
Сниппет показывает содержимое Excel-файла

Запись в Excel-файл

Создаётся новый файл Excel с таблицей под названием NewSheet:

Сниппет показывает содержимое Экселя
Сниппет показывает содержимое Экселя

Чтение таблицы SQL

Мы может читать данные из SQL-таблицы

library(RODBC)
db <- odbcDriverConnect('driver={SQL
Server};server=SERVERNAME;database=DATABASENAME;trusted_connection=true')
res <- sqlQuery(db, 'SQL QUERY')

Запись в таблицу SQL

Можем записывать данные в SQL-таблицы.

sqlSave(odbcConnection, some data frame, tablename="TABLE", append=TRUE, rownames=FALSE)

16. Статистические вычисления в R

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

Заполнение недостающих значений

Одна из самых частых задач в проекте исследования данных — это заполнение пропущенных значений. Мы можем пользоваться is.na(), чтобы найти элементы, которые имеют нулевое значение (NA (Not Available — «не доступно») или NAN (Not a Number — «не число»)):

vec <- c("test", NA, "another test")
is.na(vec)

В результате выведется FALSE TRUE FALSE (ложно, истинно, ложно), указывая на второй элемент в NA. 

Чтобы вы лучше разобрались, скажу, что is.na() возвращает все те элементы NA. А функция is.nan() вернёт все объекты NaN. Важно помнить, что NaN это NA, но не наоборот. NA не является NaN. 

Заметка: многие статистические функции, например mean, median, и так далее, принимают аргумент na.rm — он указывает, хотим ли мы удалить (переместить) na (недостающие значения). 

Некоторые вычисления далее будут производиться на следующих двух векторах:

Оба вектора A и B содержат числовые значения 20-ти элементов.

Среднее арифметическое значение

Среднее арифметическое значение вычисляется путем сложения значения в множестве и затем делением на общее количество значений:

my_mean <- mean(A)
print(my_mean)

Медиана

Медиана — среднее значение в отсортированном множестве. Если количество значений четное, то медиана будет средним значением двух значений в середине:

my_median <- median(A)
print(my_median)

Мода

Она показывает самое часто повторяющееся значение. В R нет стандартной встроенной функции для вычисления моды. Но при этом мы можем создать функцию для такого расчёта, смотрите на пример:

Вот, что происходит при выполнении этого кода:

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

Среднеквадратичное отклонение

Среднеквадратичное отклонение — это отклонение от значений среднего арифметического. 

sd <- sd(A)
print(sd)

Дисперсия 

Дисперсия — это среднеквадратичное отклонение в квадрате:  

var <- var(A)
print(var)

Корреляция

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

cor <- cor(A, B)
print(cor)

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

Помещайте метод корреляции в аргумент метода.

Окончание материала будет в третьей части…

Части также:

Читайте нас в телеграмме и vk

Перевод статьи Farhad Malik: R — Statistical Programming Language