Язык R

ToDo статьи:


Содержание

Общее описание языка R

R — простой и полезный язык для статистики, машинного обучения и DataMining, распространяемый по лицензии GNU GPL 2.

Главная страница проекта: http://www.r-project.org/

Скачать бинарники R можно здесь (российское зеркало, доступны версии для UNIX (Linux), Windows, OS X). Пользователям Ubuntu и Debian скачивать ничего не нужно: можно установить пакеты r-base, r-base-dev, r-base-cor:

 $ sudo apt-get update && apt-get install r-base r-base-dev r-base-core

Более подробно об установке R можно прочитать тут.

История создания

В 1976 году сотрудники AT&T Bell Labs: Джон Чамберс, Рик Беккер и Алан Вилкс — создали язык программирования S (от англ. «statistics»).

В 1993 году в стране, где на десять жителей приходится двадцать овец, три хоббита и два эльфа, двумя сотрудниками Оклендского университета Россом Ихака и Робертом Джентльменом (это не шутка-) на основе языка S был разработан язык R. Язык, как и его предшественник, был разработан преимущественно для статистических целей, а его название было, во-первых, подражанием названию языка S, во-вторых, это была первая буква имен разработчиков (несмотря на то, что полное имя Росса Ихака — Джордж Росс Ихака). Разработчик языка S Джон Чамберс входит в R Core Team.

Соглашения оформления кода

  1. Оператор присвоения <- вместо = (соблюдение этого соглашения показывает, что вы super high-level extremely professional advanced R-programmer, кроме того, это придаёт коду изящную «эрность»-).
  2. Имена переменных записываются в lowerCamelCase, например: monthlyAnnuity, numberOfIterations.
  3. Имена функция в UpperCamelCase: CalculateAnnuity, GetNextValue, SubstractUniqueSubstrings.
  4. В некоторых случаях, когда это целесообразно, используется венгерская нотация: vPayments — вектор, dfPayments — таблица (data.frame).
  5. etc. — добавить

Программа «Hello, world!»

Для присвоения переменной значения в R используется оператор <-. Оператор = также поддерживается, но не соответствует соглашениям. Поэтому во всех дальнейших примерах использовует только оператор <-.

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

 > hw <- "Hello, world!"
 > + print(hw)
 [1] "Hello, world!"

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

 > hw <- "Hello, world!"
 > + print(HW)
 Ошибка в print(HW) : объект 'HW' не найден

Оператор присвоения работает в обе стороны, поэтому можно писать как <-, так и ->.

 > # в R нет многострочных комментариев
 > + "Hello, world!" -> hw
 > + hw  # такой способ работает только в интерактивном режиме
 [1] "Hello, world!"

Иногда удобно вывести на печать переменную сразу после присвоения значения. Для этого используется заключение операции присвоения в круглые скобки. Подобная конструкция возможна также только в интерактивном режиме.

 > (hw <- "Hello, world!")
 [1] "Hello, world!"

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

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

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

  • библиотеки высокоуровневых ЯП (Seismic UNIX в Си, Pandas в Python) и специализированные языки для математических (включая статистические) вычисления: GNU Octave, Julia, MATLAB, MATCAD
  • «взбесившиеся» научные калькуляторы: помимо R к ним относятся Gretl (GNU Regression, Econometrics and Times-series Library), GAUSS, EViews.
  • «взбесившиеся» табличные процессоры: работа с ними напоминает MS Excel, у которого оставили только VBA-редактор (например, SAS Base — фактический стандарт в банковской и страховой индустриях, STATA или Statistica) или существенно урезали возможности редактирования редактирования ячеек и «кнопочные» функции и меню (SPSS и SAS Enterprise Guide).

R можно использовать как хороший научный и статистический калькулятор.

С его помощью можно выполнять элементарные арифметические действия:

2 + 2
 [1] 4

Можно выполнять чуть более сложные:

12 + 5 * (3 - 7) + 24 / 4.8
 [1] -3

Можно работать через переменные:

a <- 2
b <- 3
(c <- a + b)
(c <- c + 6)
 [1] 5
 [1] 11

А можно использовать и для довольно сложных вычислений. В примере - вычисление значения функции Гомпертца.

# https://goo.gl/LQ0NjQ — функция Гомпертца

#  параметры функции: заметим, что b, c < 0
a <- 0.993   # верхняя ассимптота
b <- -2.63   # смещение по t (оси абсцисс — оси времени)
c <- -1.257  # масштабирование по t (оси абсцисс — оси времени)

#  аргумент функции
t <- 6.2567  # момент времени

# вычисление значения функции Гомпертца в указанный момент времени с заданными параметрами
gompertzValue <- a * exp(b * exp(c * t))

# функция cat() объединяет свои аргументы в одну строку
# "\n" означает перевод каретки на новую строку
cat("Gompertz Value = ", gompertzValue, "\n")
 [1] Gompertz Value =  0.9919975

Векторы

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

Для инициализации переменной-вектора кроме оператора присвоения <- используется также оператор c(). С его помощью можно создать любой вектор, включая «пустой», т.е. не содержащий ни одного значения. Длина такого вектора будет равняться нулю.

(empVec <- c())  # пустой вектор
empVecLen <- length(empVec)  # функция length() возвращает длину вектора
 [1] NULL
 [1] 0

Векторы имеют фундаментальное значение в R. Часто говорят, что R — полностью векторный язык. Например, в циклы в R проходят по элементам вектора. Пример задания такого вектора (не требуется оператора c()):

vec <- 1:5
# кто сказал «Похоже на Питон»?
vec
 [1] 1 2 3 4 5

Векторы также можно задать простым перечислением его элементов.

vec <- c(1, 5, 12, 6.78, 5.4645)
vec
 [1]  1.0000  5.0000 12.0000  6.7800  5.4645

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

vec <- c(1, 5, 12, 6.78, 5.4645)
vec[1]		# первый элемент
vec[2:4]	# элементы со второго по четвёртый
vec[c(1, 3:5)]  # первый элемент и элементы с третьего по пятый
 [1] 1
 [1]  5.00 12.00  6.78
 [1]  1.0000 12.0000  6.7800  5.4645

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

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

a <- 1
# функция is.vector() возвращает значение ИСТИНА,
# если её аргумент — вектор, иначе — ЛОЖЬ
is.vector(a)
 [1] TRUE

В оператор c(), как уже, наверное, понятно, можно передавать вектора, например:

firstVec  <- c(1, 3:5)
secondVec <- c(7, 9:11)

thirdVec <- c(firstVec, secondVec)
thirdVec
 [1]  1  3  4  5  7  9 10 11

Числовые вектора в R — важный, но всё же частный случай. Вектор, как контейнер данных, может хранить и нечисловые значения. Можно задать вектор, состоящий из строк.

vec <- c("one", "two", "three")
vec[2]
 [1] "two"

Если в векторе встречаются и строки, и числа, то все элементы вектора, будут строками.

vec <- c(1, "two", 3)
# функция is.numeric() возвращает значение ИСТИНА, если ее аргумент - число, иначе ЛОЖЬ
is.numeric(vec[1])
 [1] FALSE

Функции, циклы и ветвления

Синтаксис любой функции в R выглядит следующим образом:

FunctionName <- function(<argument1> <, argument2> <, ...>) {
    # R-code
    <return(valueToReturn)>
}

Можно использовать упрощенный синтаксис (что делать крайне не советую — АтрашкевичАндрей)

FunctionName <- function(<argument1> <, argument2> <, ...>)
    # R-code
    <return(valueToReturn)>

Примеры функций:

# Пример 1: квадрат числа
SquareOfNum <- function(x) {
    res <- x ^ 2
    return(res)
}

arg    <- 2.65
result <- SquareOfNum(arg)
result
 [1] 7.0225
# Пример 2 : экспонента первого числа минус куб второго
ExpMinusCube <- function(x, y) {
   res <- exp(x)
   res <- res - x**3  # степень можно записать и как «^», и как «**»
   return(res)
}

a <- 2.56
b <- 1.75

res <- ExpMinusCube(a, b)
res
 [1] -3.841399

В качестве аргументов функции может выступать любой (?почти любой) объект R: вектор, число (вектор единичной длины), строка, таблица (data.frame) и т.п.

# Пример 3: норма n-мерного вектора
NormaVectora <- function(vect) {
    # эта конструкция позволяет остановить исполнение функции, если
    # аргумент в операторе stopifnot принимает значение ЛОЖЬ
    stopifnot(is.vector(vect))  # проверяем, что переданный аргумент — вектор
    
    # норма вектора в линейном пространстве — квадратный корень суммы квадратов координат
    res <- sqrt(sum(vect*2)) 
    return(res)
}

someVec <- c(7, 8, -3)
vecNorm <- NormaVectora(someVec)
vecNorm
 [1] 4.898979

Циклы

Цикл (любого типа) — базовая конструкция практически любого языка программирования.

Синтаксис цикла типа for (цикла со счётчиком) в R выглядит следующим образом:

for (i in vect) {
    # тело цикла
}

Вместо i может быть, естественно, любое другое приемлемое имя переменной.

Как было сказано выше, цикл в R проходит значения вектора. Чтобы проиллюстрировать это, приведём несколько примеров.

# Пример цикла 1:
for (i in 1:5) {
    print(i) 
}
 [1] 1
 [1] 2
 [1] 3
 [1] 4
 [1] 5
# Пример цикла 2:
vLoop <- c(1:3, 100:105)
print("вектор обхода")
vLoop

print("обход цикла")
for (i in vLoop) {
    print(i)
}
 [1] "вектор обхода"
 [1]   1   2   3 100 101 102 103 104 105
 [1] "обход цикла"
 [1] 1
 [1] 2
 [1] 3
 [1] 100
 [1] 101
 [1] 102
 [1] 103
 [1] 104
 [1] 105

Если необходимо задать шаг итерации, то запись несколько отличается:

 for(itarator.name in seq(start.value, stop.value, by = by.value)){
   # code
 }

 # инкрементное решение
FuncFactorialIteraion <- function(n){
  stopifnot (n > 0)  # если условие в скобках не ИСТИНА, значит прекращается исполнение
  factorial <- 1
  for (i in 1:n) {
    factorial <- factorial * i
   }
  return(factorial)
}
FuncFactorialIteraion(5)

Для проверки условий ветвлений используются логические выражения (принимающие одно из возможных значений: ИСТИНА или ЛОЖЬ). Для записи логических выражений используются логические операторы И, ИЛИ, НЕ. В синтаксисе R: &, |, ! — соответственно.

Синтаксис ветвления:

 #condition.1, ..., condition.N - логические выражения
 if (condition.1) {
   # code если условие condition.1 - ИСТИНА
 } else if (condition.2) {
   # code если условие condition.2 - ИСТИНА
 # ...
 } else if (condition.N) {
   # code если условие condition.N - ИСТИНА 
 } else {
   # code если condition.1 ... condition.N все ЛОЖЬ
 }

 # рекурсивное решение
FuncFactiorialRecur <- function(n) {
  stopifnot (n >= 0)
  if (n == 0) {
    return(1)
  } else {
    return(n * FuncFactiorialRecur(n - 1))  # вызов функции из самой себя (рекурсивный вызов)
  }
} 
FuncFactiorialRecur(4)

Числа Фибоначчи

# последовательность Фибоначчи F = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...}:
# начиная с третьего элемента (первый и второй — 0 и 1 соответственно) значение
# элемента последовательности равно сумме предыдущих двух элементов
FiboSeries <- function(n) {
  stopifnot (n > 0)
  if (n == 1) {
    return(0)
  } else if (n == 2) {  # обратите внимание на пробел между else и if
    return(1)
  } else {
    return(FiboSeries(n - 1) + FiboSeries(n - 2))
  }
}
FiboSeries(8)
 [1] 13

Использование языка

Язык R — монокультура экономико-математических вычислений. Он прекрасно подходит как для эконометристов (здесь должна быть шутка про количественных экономистов и метеорологов), лоботомированных микро- и макро- экономикой в их современном изводе, так и для технарей-математиков-программистов, которые работают в сфере количественных финансов (для них чаще всего лоботомия происходила в форме из-рук-вон-преподавания-программирования). Благодаря чрезвычайно низкому порогу вхождения, элементарному до дебилизма синтаксису, фантастической распространённости и большому количеству написанных библиотек (QWERTY-эффект), возможности писать код использую преимущественно спинной мозг, R может, по скромному мнению одного из авторов статьи, получить почётное звание «Вижал Васик нашего поколения для статистиков и экономистов».

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

Сравнение с другими языками

Следующей монокультурой в пространстве статистических языков программирования по моим прогнозам (АтрашкевичАндрей) должен стать язык Julia. Уже есть некоторые указания на то, что этот процесс запущен и идет. Например, Julia начинают пиарить в «илитных» ВУЗах и факультетах по математическим методам в экономике и по прикладной математике в экономике. До R монокультурой был EViews (пиарился эконометристами РЭШ) и, частично, gretl (пиарился эконометристами ВШЭ). Монокультурой на ПМ-ПУ СПбГУ (привсем уважении) был, есть и остается MATLAB (и его детище SimuLink). Хотя 98% «экономистов» дальше =СУММЕСЛИ() в MS Excel вообще ничего никогда не используют.

Литература

  1. R Language Definition. Version 3.3.1 (2016-06-21) DRAFT / R Core Team. — 2014. — 60 p. — http://cran.r-projec....
  2. Venables, W. N. An Introduction to R. Notes on R: A Programming Environment for Data Analysis and Graphics. Version 3.3.1 (2016-06-21) / W. N. Venables, D.M. Smith, Core Team R. — W. N. Venables, D. M. Smith and the R Core Team, 2014. — 105 p. — http://cran.r-projec....
  3. Paradis, E. R for beginners / E. Paradis. — 2005. — 72 p. — http://cran.r-projec....
  4. Matloff, N. The Art of R Programming / Norman Matloff. — 2009. — 193 p. — http://heather.cs.uc....

К: The Art of R Programming — книга для тех, кто знаком (и знаком неплохо) с программированием. В ее приложениях находится хороший список литературы, включая ссылки на интернет-источники. --АтрашкевичАндрей


КатегорияЯзыкиПрограммирования