7.5 Indexação de vetores

Os elementos de um vetor são indexados e para acessá-los usamos a notação de índices do . Para extrair ou filtrar elementos de um vetor usamos o operador colchetes [ ], seguindo a sintaxe:

vetor[indices]

onde indices representa o vetor com os índices dos elementos da variável vetor a serem selecionados. O operador [ quando aplicado a um vetor retornará sempre um vetor.

Para acessar partes um elemento de um vetor o vetor indices dentro dos colchetes pode ser especificado de diferentes formas:

  • por posições (vetor numérico)

  • por nomes (vetor de caracteres)

  • por comparações, testes ou condições (vetor lógico)

7.5.1 Indexação por vetores numéricos

7.5.1.1 Positivos

Para extrairmos a precipitação de janeiro e dezembro do vetor prec podemos usar o seguinte código:

# vetor com as posições dos meses de janeiro e dezembro
c(1, length(prec))
#> [1]  1 12
# acesso aos valores localizados nas posições 1 e 12 
prec[c(1, length(prec))]
#> jan dez 
#> 300 280

Passando um vetor numérico entre os colchetes retorna a parte do vetor contendo os elementos daquelas posições.

Similarmente a precipitação dos meses de inverno (Junho, Julho e Agosto) podem ser selecionadas usando um vetor definido com os índices das posições daqueles meses:

inds_jja <- 6:8
# vetor de chuva JJA
prec[inds_jja]
#> jun jul ago 
#>   0  12  22

O reposicionamento dos elementos de um vetor pode ser feito pela especificação da ordem dos índices. Par ordenar os elementos na ordem dezembro, Janeiro e Fevereiro indexamos da seguinte maneira:

prec[c(12, 1, 2)]

A inversão da ordem dos elementos pode ser feita com a indexação:

prec[length(prec):1]

A função rev() economiza tempo de digitação de código para realizar esta mesma ação:

rev(prec)

7.5.1.2 Negativos

O acesso aos dados de precipitação de janeiro e dezembro do vetor prec poderia ser feita uma lógica complementar. Poderíamos selecionar todos elementos de prec exceto aqueles entre Fevereiro (posição 2) e Novembro (posição 11). Esta frase poderia ser transcrita em código R, simplesmente como -(2:11). O sinal - precedendo o vetor numérico, exclui o acesso aquelas posições quando usado entre o operador [.

prec[-(2:11)]
#> jan dez 
#> 300 280

Analogamente, os meses de inverno poderiam ser selecionados com:

 prec[-c(1:5, 9:12)]
#> jun jul ago 
#>   0  12  22

7.5.2 Indexação por nomes

A seleção de partes e um vetor pode ser feita também usando os nomes de seus elementos. As precipitações de janeiro e dezembro poderiam ser extraídas usando os nomes daqueles elementos:

prec[c("jan", "dez")]
#> jan dez 
#> 300 280

Assim como as precipitações de inverno.

prec[c("jun", "jul", "ago")]
#> jun jul ago 
#>   0  12  22

7.5.3 Indexação por vetores lógicos

Vamos criar um vetor lógico e usá-lo para a seleção com um vetor lógico dos elementos de prec para Janeiro e Dezembro.

inds_log <- c(
  TRUE, FALSE, FALSE, FALSE,
  FALSE, FALSE, FALSE, FALSE,
  FALSE, FALSE, FALSE, TRUE
)
prec[inds_log]
#> jan dez 
#> 300 280

Somente os elementos de inds_log correspondentes a TRUE foram selecionados.

Vetores lógicos são muito úteis quando aproveitamos a funcionalidade de coerção. Imagine que você queira extrair de prec o primeiro elemento, mas o segundo não, o terceiro elemento sim, o quarto não e assim sucessivamente. Essa seleção intercalada pode ser simplesmente feita com:

inds_log <- c(TRUE, FALSE)
prec[inds_log]
#> jan mar mai jul set nov 
#> 300 210   0  12 100  10

Uma forma mais prática de filtrar vetores é por comparações. Por exemplo, quais valores de precipitação foram acima de 80 mm?

inds_prec_alta <- prec > 80
prec[inds_prec_alta]
#> jan fev mar set out dez 
#> 300 200 210 100 120 280

Vimos que a filtragem consiste em extrair elementos de um vetor que satisfaça uma ou várias condições. Entretanto, em alguns casos, o interesse está nas posições do vetor que atendem a condição (onde ela é verdadeira). Nós podemos localizar essas ocorrências usando a função which(). Por exemplo, qual a posição dos elementos do vetor inds_prec_alta que são verdadeiros?

which(inds_prec_alta)
#> jan fev mar set out dez 
#>   1   2   3   9  10  12

A função which() converte um vetor lógico em numérico, somente os índices em que a condição é TRUE.

A utilidade da which() é mais evidente quando usada para, por exemplo, sabermos qual o mês do 4° caso mais chuvoso.

which(inds_prec_alta)[4]
#> set 
#>   9
names(which(inds_prec_alta)[4])
#> [1] "set"
# ou
names(prec)[which(inds_prec_alta)[4]]
#> [1] "set"

A resultado da which() é um vetor numérico e portanto equivale a indexação numérica. Então a seleções abaixo são equivalentes:

prec[which(inds_prec_alta)]

prec[inds_prec_alta]

Quando é melhor usar uma ou outra opção? Note que o resultado de which(inds_prec_alta) armazena somente os índices que satisfazem a condição, enquanto que o resultado de inds_prec_alta é um vetor lógico de mesmo tamanho que prec. Então, se estiver trabalhando com big data (p.ex.: um vetor com milhões de elementos) em termos de eficiência de uso da memória a which() é melhor opção.

Para localizar valores extremos em um vetor podemos usar as funções which.max() e which.min() que fornecem respectivamente, a posição do valor máximo e mínimo no vetor. Elas são versões eficientes dos códigos which(x == max(x)) e which(x == min(x)). Contudo, há uma diferença entre elas que pode ser verificada pela comparação dos resultados das instruções:

which.min(prec)

which(prec == min(prec))

A primeira seleciona o primeiro índice para o qual prec tem seu mínimo (5° elemento), enquanto a segunda retorna todos os índices correspondentes ao mínimo (5° e 6° elemento).