3.6 Vetores

Vetores são estruturas muito importantes dentro R. Em especial, pensando em análise de dados, precisamos estudá-los pois cada coluna de um data frame será representada como um vetor.

Vetores no R são apenas conjuntos indexados de valores. Para criá-los, basta colocar os valores separados por vírgulas dentro de um c().

vetor1 <- c(1, 5, 3, -10)
vetor2 <- c("a", "b", "c")

vetor1
## [1]   1   5   3 -10
vetor2
## [1] "a" "b" "c"

Os objetos vetor1 e vetor2 são vetores.

Uma maneira fácil de criar um vetor com uma sequência de números é utilizar o operador :.

# Vetor de 1 a 10
1:10
##  [1]  1  2  3  4  5  6  7  8  9 10

# Vetor de 10 a 1
10:1
##  [1] 10  9  8  7  6  5  4  3  2  1

# Vetor de -3 a 3
-3:3
## [1] -3 -2 -1  0  1  2  3

Quando dizemos que vetores são conjuntos indexados, isso quer dizer que cada valor dentro de um vetor tem uma posição. Essa posição é dada pela ordem em que os elementos foram colocados no momento em que o vetor foi criado. Isso nos permite acessar individualmente cada valor de um vetor.

Para isso, colocamos o índice do valor que queremos acessar dentro de colchetes [].

vetor <- c("a", "b", "c", "d")

vetor[1]
## [1] "a"
vetor[2]
## [1] "b"
vetor[3]
## [1] "c"
vetor[4]
## [1] "d"

Você também pode colocar um conjunto de índices dentro dos colchetes, para pegar os valores contidos nessas posições:

vetor[c(2, 3)]
## [1] "b" "c"
vetor[c(1, 2, 4)]
## [1] "a" "b" "d"

Essa operação é conhecida como subsetting, pois estamos pegando subconjuntos de valores de um vetor.

Se você tentar acessar uma posição do vetor que não existe, ele retornará NA, indicando que esse valor não existe. Discutiremos o que são NA’s na Seção 3.8.

vetor[5]
## [1] NA

Um vetor só pode guardar um tipo de objeto e ele terá sempre a mesma classe dos objetos que guarda. Para saber a classe de um vetor, rodamos class(nome-do-vetor).

vetor1 <- c(1, 5, 3, -10)
vetor2 <- c("a", "b", "c")

class(vetor1)
## [1] "numeric"
class(vetor2)
## [1] "character"

Se tentarmos misturar duas classes, o R vai apresentar o comportamento conhecido como coerção.

vetor <- c(1, 2, "a")

vetor
## [1] "1" "2" "a"
class(vetor)
## [1] "character"

Veja que todos os elementos do vetor se transformaram em texto. Agora temos um vetor com o texto "1", o texto "2" e o texto "a". Como um vetor só pode ter uma classe de objeto dentro dele, classes mais fracas serão sempre reprimidas pelas classes mais fortes. Como regra de bolso: caracteres serão sempre a classe mais forte. Então, sempre que você misturar números e texto em um vetor, os números virarão texto.

Falaremos bastante de coerção nas próximas seções e capítulos, trazendo exemplos de quando ela ajuda e de quando ela atrapalha.

De forma bastante intuitiva, você pode fazer operações com vetores.

vetor <- c(0, 5, 20, -3)
vetor + 1
## [1]  1  6 21 -2

Ao rodarmos vetor1 + 1, o R subtrai 1 de cada um dos elementos do vetor. O mesmo acontece com qualquer outra operação aritmética.

vetor - 1
vetor / 2
vetor * 10

Você também pode fazer operações que envolvem mais de um vetor:

vetor1 <- c(1, 2, 3)
vetor2 <- c(10, 20, 30)

vetor1  + vetor2
## [1] 11 22 33

Neste caso, o R irá alinhar os dois vetores e somar elemento a elemento. Esse tipo de comportamento é chamado de vetorização. Isso pode ficar um pouco confuso quando os dois vetores não possuem o mesmo tamanho. Tente adivinhar qual será a saída do código a seguir:

vetor1 <- c(1, 2)
vetor2 <- c(10, 20, 30, 40)

vetor1 + vetor2
## [1] 11 22 31 42

Embora estejamos somando dois vetores de tamanho diferentes, o R não devolve um erro (o que parecia ser a resposta mais intuitiva). O R alinhou os dois vetores e, como eles não possuíam o mesmo tamanho, o primeiro foi repetido para ficar do mesmo tamanho do segundo. É como se o primeiro vetor fosse na verdade c(1, 2, 1, 2). Esse comportamento é chamado de reciclagem.

Embora contra-intuitiva, a reciclagem é muito útil no R graças a um caso particular muito importante. Quando somamos vetor + 1 no nosso primeiro exemplo, o que o R está fazendo por trás é transformando o 1 em c(1, 1, 1, 1) e realizando a soma vetorizada c(0, 5, 20, -3) + c(1, 1, 1, 1). Isso porque o número 1 nada mais é do que um vetor de tamanho 1, isto é, 1 é igual a c(1).

Usaremos esse comportamento no R o tempo todo e é muito importante a reciclagem para termos certeza de que o R está fazendo exatamente aquilo que gostaríamos que ele fizesse.

Um outro caso interessante de reciclagem é quando o comprimento dos vetores não são múltiplos um do outro.

vetor1 <- c(1, 2, 3)
vetor2 <- c(10, 20, 30, 40, 50)

vetor1 + vetor2
## Warning in vetor1 + vetor2: longer object length is not a multiple of shorter
## object length
## [1] 11 22 33 41 52

Neste caso, duas coisas aconteceram:

  1. O R realizou a conta, repetindo cada valor do primeiro vetor até que os dois tenham o mesmo tamanho. No fundo, a operação realizada foi c(1, 2, 3, 1, 2) + c(10, 20, 30, 40, 50).

  2. Como essa operação é ainda menos intuitiva e raramente desejada, o R devolveu um aviso dizendo que o comprimento do primeiro vetor maior não é um múltiplo do comprimento do vetor menor.


Curso-R