Еще немного про векторы

Поименованные векторы

Помимо обычных векторов (наборов элементов) в 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