Це - велика концепція в R. Щоб краще зорієнтуватися в цих можливостях, корисно розглянути розмірність вхідних і вихідних даних різних функцій.
Ми вже бачили функції, які приймають вектор і повертають єдине значення, подібне до скаляра:
v <- 1:5
length(v)
#> [1] 5
sum(v)
#> [1] 15
До цієї категорії належать і багато статистичних функцій, як-от mean().
Для логічних векторів є all() і any(), які повертають єдине TRUE або FALSE.
Багато функцій в R працюють з цілими векторами й часто повертають вектор. Це стосується більшості математичних функцій:
sq <- c(4, 9, 16, 25)
sqrt(sq) # square root
#> [1] 2 3 4 5
Це не лише лаконічно й зручно: ми оминаємо потребу в циклах, спискових включеннях чи рекурсії, поширених в інших мовах. У R векторні функції часто працюють значно швидше, ніж ці прийоми.
Ми вже використовували векторні функції частіше, ніж, імовірно, усвідомлювали. Порівняймо:
v <- c(2, 7, 9)
w <- c(3, 1, 5)
v + w
#> [1] 5 8 14
"+"(v, w)
#> [1] 5 8 14
Звичні інфіксні оператори - це лише синтаксичний цукор для відповідної векторної функції! У цьому випадку "+"().
Для сортування вектора є sort(), що повертає значення, і order(), що повертає індекси:
v <- c("I", "am", "not", "in", "order")
sort(v)
#> [1] "am" "I" "in" "not" "order"
order(v)
#> [1] 2 1 4 3 5
Типово сортування відбувається за зростанням.
За потреби вкажімо decreasing = TRUE або скористаймося rev(), щоб обернути наявний вектор.
v <- c("I", "am", "not", "in", "order")
sort(v, decreasing = TRUE)
#> [1] "order" "not" "in" "I" "am"
rev(1:4)
#> [1] 4 3 2 1
Є також функції, як-от cumsum() і cumprod(), які створюють накопичувальні вектори, обробляючи вхідний вектор зліва направо:
cumsum(1:5)
#> [1] 1 3 6 10 15 # sums
cumprod(1:5)
#> [1] 1 2 6 24 120 # equivalent to factorials
Наведені приклади схожі на операції foldl у багатьох функціональних мовах, хіба що на виході отримуємо вектор з усіма проміжними значеннями.
Цю концепцію можна поширити й на порівняння векторів.
Наприклад, розгляньмо функцію попарного максимуму pmax():
v
#> [1] 2 7 9
w
#> [1] 3 1 5
pmax(v, w)
#> [1] 3 7 9 # max of each pairwise comparison
Ця функція та інші подібні до неї приймають довільну кількість вхідних векторів, а не лише два.
У наведеному прикладі використано вектори однакової довжини. Як обговорювалося в концепції Фільтрування векторів, R застосовує перевикористання, щоб подовжити вектори, які чомусь «занадто короткі». Повторимо: застосовуймо це обережно і, бажано, лише до вектора довжиною 1.
pmax(v, 5)
#> [1] 5 7 9
Це менш поширений випадок, але досить легко написати функції, які на вигляд приймають скаляр, а повертають вектор.
Коли застосувати їх до вектора, на виході отримуємо двовимірну matrix (про неї йдеться в пізнішій концепції).