Este é um conceito amplo em R. Para ajudar a compreender as possibilidades, pode ser útil pensar na dimensionalidade do que entra e do que sai das várias funções.
Já vimos funções que recebem um vetor e devolvem um único valor do tipo escalar:
v <- 1:5
length(v)
#> [1] 5
sum(v)
#> [1] 15
Muitas funções estatísticas também pertencem a esta categoria, como mean().
Para vetores lógicos, existem all() e any(), que devolvem um único TRUE ou FALSE.
Muitas funções em R operam sobre vetores inteiros e devolvem, muitas vezes, um vetor como resultado. Isto inclui a maioria das funções matemáticas:
sq <- c(4, 9, 16, 25)
sqrt(sq) # square root
#> [1] 2 3 4 5
Isto não é apenas conciso e prático: evita a necessidade de ciclos, de compreensões de listas ou de recursão, tão comuns noutras linguagens. Em R, as funções vetoriais são muitas vezes muito mais rápidas do que essas técnicas.
Já usaste funções vetorizadas mais do que provavelmente imaginas. Compara estas:
v <- c(2, 7, 9)
w <- c(3, 1, 5)
v + w
#> [1] 5 8 14
"+"(v, w)
#> [1] 5 8 14
Os operadores infixos que conheces não passam de açúcar sintático para a função vetorizada subjacente! Neste caso, "+"().
Para ordenar um vetor, existe sort(), que devolve os valores, e order(), que devolve os índices:
v <- c("I", "am", "not", "in", "order")
sort(v)
#> [1] "am" "I" "in" "not" "order"
order(v)
#> [1] 2 1 4 3 5
Por omissão, a ordenação é feita por ordem crescente.
Especifica decreasing = TRUE se for necessário, ou usa rev() para inverter um vetor existente.
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
Existem também funções como cumsum() e cumprod(), que produzem resultados cumulativos em forma de vetor, operando sobre o vetor de entrada da esquerda para a direita:
cumsum(1:5)
#> [1] 1 3 6 10 15 # sums
cumprod(1:5)
#> [1] 1 2 6 24 120 # equivalent to factorials
Os exemplos acima são semelhantes a operações foldl em muitas linguagens funcionais, exceto que o resultado é um vetor com todos os valores intermédios.
Uma extensão deste conceito também pode ser usada para comparar vetores.
Por exemplo, considera a função de máximo par a par pmax():
v
#> [1] 2 7 9
w
#> [1] 3 1 5
pmax(v, w)
#> [1] 3 7 9 # max of each pairwise comparison
Esta função e outras semelhantes também aceitam um número arbitrário de vetores de entrada, não apenas dois.
O exemplo acima usa vetores do mesmo comprimento. Como se explicou no conceito Filtragem de Vetores, R usa a reciclagem para estender vetores que são, de alguma forma, "demasiado curtos". Repetindo: usa isto com cuidado e, de preferência, apenas com um vetor de comprimento 1.
pmax(v, 5)
#> [1] 5 7 9
Isto é menos comum, mas é bastante fácil escrever funções que, aparentemente, recebem um escalar e devolvem um vetor.
Quando aplicadas a um vetor, o resultado é uma matrix bidimensional (abordada num conceito posterior).