Сначала загружаем пакет для строительства красивых графиков:
library(ggplot2)
R можно использовать как весёлый калькулятор:
5 + 9
## [1] 14
Что-нибудь более интересное:
a <- factorial(4)
b <- 2^3
a + b
## [1] 32
Признайся, шалунишка, ты всегда мечтал поделить на ноль?
a <- 1 / 0
a
## [1] Inf
Что можно делать с бесконечностью?
1 / (a - 9)
## [1] 0
Возьмём арктангенс!
atan(Inf)
## [1] 1.570796
Ба! Да это же \(\pi/2\):
pi / 2
## [1] 1.570796
Но с неопределенностью ничего не поделаешь:
0 / 0
## [1] NaN
NaN расшифровывается как «Not a Number». NaN отличается от NA («Not Available», пропущенные данные); точнее, всякое NaN — NA, но не всякое NA — NaN. Проверять, является ли что-либо NA или NaN, можно так:
is.na(0 / 0)
## [1] TRUE
a <- NA
is.na(a)
## [1] TRUE
is.nan(a)
## [1] FALSE
Вектор из чисел по порядку:
a <- 3:10
a
## [1] 3 4 5 6 7 8 9 10
Вектор из одинаковых чисел:
b <- rep(777, times = 5)
b
## [1] 777 777 777 777 777
Вектор из конкретных чисел:
vect <- c(5, -4, 1)
Что можно делать с вектором?
sum(vect)
## [1] 2
Хотите среднее арифметическое?
mean(vect)
## [1] 0.6666667
Хочу 300 случайных натуральных чисел от 1 до 5 с повторами! И побыстрее!
h <- sample(1:5, 300, rep = TRUE)
Краткая информация о векторе \(h\), начало вектора \(h\) и конец вектора \(h\):
str(h)
## int [1:300] 2 4 2 5 2 5 1 3 4 3 ...
head(h)
## [1] 2 4 2 5 2 5
tail(h)
## [1] 3 4 3 2 5 4
Команды head()
и tail()
позволяют отобразить не только шесть первых значений (по умолчанию), но и заданное их число:
head(h, n = 2)
## [1] 2 4
Или без последних значений:
head(h, n = -298)
## [1] 2 4
Хочу сгенирировать выборку из 100 значений случайной величины \(X\) с вероятностями:
\(X\) | -2 | 3 | 7 |
---|---|---|---|
\(P()\) | 0.1 | 0.2 | 0.7 |
Зададим вектор вектор возможных значений и вектор вероятностей:
x.val <- c(-2, 3, 7)
x.pr <- c(0.1, 0.2, 0.7)
Получаем выборку из 100 значений:
s <- sample(x.val, 100, rep = TRUE, x.pr)
str(s)
## num [1:100] 7 3 7 7 7 7 3 7 7 7 ...
Простенькую гистограмму можно построить, например, с помощью функции qplot()
из пакета ggplot2
:
qplot(factor(s), xlab = "Значение", ylab = "Количество", main = "Гистограмма")
Ту же гистограммку можно построить с помощью функции ggplot()
из того же пакета, предварительно преобразовав s в необходимый для ggplot()
формат data frame:
s_df <- data.frame(s)
ggplot(s_df) + geom_bar(aes(factor(s))) + labs(x = "Значение", y = "Количество", title = "Гистограмма")
И еще простенький график:
x <- rnorm(500) # 500 нормальных величин со средним 0 и дисперсией 1
y <- rnorm(500) # 500 нормальных величин со средним 0 и дисперсией 1
qplot(x, y, main = "Точечки")
Или:
xy_df <- data.frame(x = x, y = y)
ggplot(xy_df) + geom_point(aes(x, y)) + labs(title = "Точечки")
В зависимости от формата данных часто бывает удобно использовать и qplot()
, и ggplot()
.
Выберем из вектора \(s\) значения больше \(0\):
b <- s[s > 0]
b
## [1] 7 3 7 7 7 7 3 7 7 7 7 7 7 7 7 7 7 3 7 7 3 7 3 7 7 3 7 7 7 7 7 3 7 7 3
## [36] 7 7 7 7 7 3 7 7 7 7 7 3 7 7 3 7 7 7 7 7 7 7 7 3 7 3 7 3 7 7 7 7 3 7 3
## [71] 7 3 3 7 3 7 7 3 7 7 3 7 3 7 7 7 7 7 7
str(b)
## num [1:89] 7 3 7 7 7 7 3 7 7 7 ...
Можно выбрать конкретные \(s\), например с 6-го по 20-ое:
s[6:20]
## [1] 7 3 7 7 7 -2 7 7 -2 7 7 7 7 7 3
Хочу 5-ое, 7-ое и 13-ое!
s[c(5, 7, 13)]
## [1] 7 3 7
Можно узнать, сколько значений равно 3:
sum(s == 3)
## [1] 22
Еще полезная штучка — количество элементов в векторе:
length(b)
## [1] 89
Операции, похожие на те, что проделали с векторами, можно делать и с другими типами данных, например, с матрицами (matrix), таблицами (table) и др. Покажем на примере наборов данных (data frame).
Будем использовать набор данных diamonds
из пакета ggplot2
. Множество других встроены во многие пакеты, а также в сам R, и список с кратким описанием последних можно вызвать командой library(help = "datasets")
.
Наборы данных состоят из строк (rows) и столбцов (columns); в каждой строке хорошо построенного набора — характеристики одного объекта, а по столбцам — значения одной характеристики у разных объектов. Так, например, в diamonds
объектами являются бриллианты, а их характеристиками — цена, вес, цвет и т. д. Это можно увидеть с помощью всё той же команды str()
:
str(diamonds)
## Classes 'tbl_df', 'tbl' and 'data.frame': 53940 obs. of 10 variables:
## $ carat : num 0.23 0.21 0.23 0.29 0.31 0.24 0.24 0.26 0.22 0.23 ...
## $ cut : Ord.factor w/ 5 levels "Fair"<"Good"<..: 5 4 2 4 2 3 3 3 1 3 ...
## $ color : Ord.factor w/ 7 levels "D"<"E"<"F"<"G"<..: 2 2 2 6 7 7 6 5 2 5 ...
## $ clarity: Ord.factor w/ 8 levels "I1"<"SI2"<"SI1"<..: 2 3 5 4 2 6 7 3 4 5 ...
## $ depth : num 61.5 59.8 56.9 62.4 63.3 62.8 62.3 61.9 65.1 59.4 ...
## $ table : num 55 61 65 58 58 57 57 55 61 61 ...
## $ price : int 326 326 327 334 335 336 336 337 337 338 ...
## $ x : num 3.95 3.89 4.05 4.2 4.34 3.94 3.95 4.07 3.87 4 ...
## $ y : num 3.98 3.84 4.07 4.23 4.35 3.96 3.98 4.11 3.78 4.05 ...
## $ z : num 2.43 2.31 2.31 2.63 2.75 2.48 2.47 2.53 2.49 2.39 ...
Отобразим наблюдения с 5-го по 7-е:
diamonds[c(5:7), ]
## carat cut color clarity depth table price x y z
## 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
## 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
## 7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47
Первые 4 значения параметров цены (price) и веса (carat):
head(diamonds[, c("price", "carat")], n = 4)
## price carat
## 1 326 0.23
## 2 326 0.21
## 3 327 0.23
## 4 334 0.29
Можно отобразить и все названия характеристик:
colnames(diamonds)
## [1] "carat" "cut" "color" "clarity" "depth" "table" "price"
## [8] "x" "y" "z"
Найдём, сколько камней имеют чистоту не меньшую, чем VS2 (характеристика clarity — упорядоченный фактор).
nrow(diamonds[diamonds$clarity >= "VS2", ])
## [1] 30940
Правда ли, что 0.4 + 0.1 равно 0.5?
0.4 + 0.1 == 0.5
## [1] TRUE
А правда ли, что 0.4 - 0.1 равно 0.3?
0.4 - 0.1 == 0.3
## [1] FALSE
Хм, что-то Марь Иванна в школе другое говорила…
Почему так случилось? Компьютер хранит числа в памяти в двоичной системе счисления. В двоичной системе обычное число 0.1 будет записываться в виде бесконечной периодической дроби. Следовательно, без дополнительных ухищрений храниться в памяти абсолютно точно оно не может. Поэтому де-факто компьютер хранит в памяти округленную версию от 0.4, 0.1 и 0.3. В данном случае при вычитании ошибки округления не компенсируют друг друга.