Помимо обычных векторов (наборов элементов) в R можно создавать поименованные векторы – наборы элементов с присвоенными им названиями. Создадим вектор с профилем некоторой страны (id, значение ВВП на душу населения, значения индекса демократии, индекс коррупции):
cntr_profile <- c(id = 10, gdp_pc = 2500, democracy = 4.6, corr_index = 2.1)
Посмотрим на структуру полученного вектора:
str(cntr_profile)
## Named num [1:4] 10 2500 4.6 2.1
## - attr(*, "names")= chr [1:4] "id" "gdp_pc" "democracy" "corr_index"
Теперь при обращении к какому-либо элемента вектора R будет выдавать не только его значение, но и название:
cntr_profile[2]
## gdp_pc
## 2500
На практике такие вектора нужны нечасто, но если мы когда-нибудь будем писать свои функции или даже библиотеки, нам может понадобиться, чтобы при выводе элемента на экран R показывал пользователю минимальную информацию об этом элементе.
Пусть у нас есть вектор p и вектор q, и мы хотим выбрать совпадающие элементы – вывести на экран те элементы в векторе q, которые есть в p.
q <- c(1, 2, 4, 1, 2, 3, 3, 2, 1, 4, 2)
p <- c(1, 2)
q[q %in% p] # 1 и 2
## [1] 1 2 1 2 2 1 2
Или наоборот - несовпадающие элементы:
q[!q %in% p] # не 1 и 2, ! - отрицание
## [1] 4 3 3 4
Может возникнуть вопрос: а нет ли более изящного способа находить общие элементы в векторах? Существуют же операции для множеств: пересечение, объединение, разность и другие…Да, в R можно работать с множествами. Например, у нас есть два множества, два вектора A и B:
A <- c(1, 9, 7, 12, 0, 5)
B <- c(1, 4, 8, 0, 24)
Посмотрим на их пересечение (общие элементы A и B):
intersect(A, B)
## [1] 1 0
А теперь на объединение (все элементы A и B):
union(A, B)
## [1] 1 9 7 12 0 5 4 8 24
На разницу (все элементы A, которых нет в B):
setdiff(A, B)
## [1] 9 7 12 5
Важно: Cтоит помнить, что множество – это вектор без повторяющихся значений. Если в интересующих нас векторах есть повторяющиеся значения, и для нас это имеет значение, то тут надо быть аккуратнее.
Сравним результаты двух операций: нахождения совпадающих элементов в двух векторах с помощью %in%
и нахождения пересечения множеств с помощью intersect()
.
v1 <- c(2, 2, 3, 4, 5, 8)
v2 <- c(6, 7, 2, 2, 9, 11)
Воспользуемся оператором %in%
:
v1[v1 %in% v2] # выдает два совпадающих значения векторов, две 2
## [1] 2 2
Воспользуемся функцией intersect()
:
intersect(v1, v2) # выдает один совпадающий элемент, одну 2, так как v1 и v2 воспринимаются как множества
## [1] 2
А как вообще выглядит множество в R? Как получить вектор без повторяющихся значений? Для этого есть функция unique()
:
unique(v1)
## [1] 2 3 4 5 8
В R можно быстро составить вектор из повторяющихся значений. Например, три раза повторить “Repeat me”:
rep('Repeat me', 3)
## [1] "Repeat me" "Repeat me" "Repeat me"
Или три раза повторить вектор с двумя значениями 0 и 1:
rep(c(1, 0), 3)
## [1] 1 0 1 0 1 0
rep(c('Yes','No'), each = 4) # повторить 4 раза каждый элемент вектора
## [1] "Yes" "Yes" "Yes" "Yes" "No" "No" "No" "No"
Можно создавать векторы с пропущенными значениями (NAs, от “not applicable”):
w <- c(0, 1, NA, NA)
w
## [1] 0 1 NA NA
is.na(w) # проверяем, является ли NA
## [1] FALSE FALSE TRUE TRUE
which(is.na(w)) # возвращаем индексы NAs
## [1] 3 4
Обратите внимание: NA указывается без кавычек! Это не текст, который кодирует пропущенные значения, а особый “вид” данных (наличие NA не изменяет тип переменной, то есть, если NA встречаются в числовой переменной, переменная будет восприниматься R как числовая).
Кроме того, если нужны векторы особого вида (например, набор букв алфавита или названий месяцев), можно взять уже встроенные в R:
letters # буквы английского алфавита
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z"
LETTERS # заглавные буквы английского алфавита
## [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q"
## [18] "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
month.name # названия месяцев
## [1] "January" "February" "March" "April" "May"
## [6] "June" "July" "August" "September" "October"
## [11] "November" "December"
month.abb # сокращенные названия месяцев
## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov"
## [12] "Dec"
Для создания векторов можно использовать последовательности (для владеющих Python: аналог range()
и arange()
, но в отличие от Python, здесь в вектор включаются оба конца). Например, последовательность из целых значений от 0 до 10:
0:10
## [1] 0 1 2 3 4 5 6 7 8 9 10
Мы можем сохранить результат в вектор my_seq
.
my_seq <- 1:10 # можем сохранить результат в вектор my_seq
my_seq
## [1] 1 2 3 4 5 6 7 8 9 10
А вот последовательность из целых начений от 1 до 3 с шагом 0.5:
seq(from = 1, to = 3, by = 0.5)
## [1] 1.0 1.5 2.0 2.5 3.0
Названия параметров можем опускать, если сохраняем их порядок:
seq(1, 3, 0.5)
## [1] 1.0 1.5 2.0 2.5 3.0