Percursos
/
R
R
/
Programa
/
Filtragem de vetores
Fi

Filtragem de vetores em R

3 exercícios

Sobre Filtragem de vetores

Vimos no conceito Vectors que um vetor pode ser usado numa expressão condicional, dando origem a um vetor lógico. Este, por sua vez, pode ser usado em funções como all() e any().

v <- c(4, 7, 10)
v >= 6
#> [1] FALSE  TRUE  TRUE
all(v > 6)
#> [1] FALSE    # not all elements match this condition
any(v > 6)
#> [1] TRUE     # at least one element matches

Esta técnica é muito mais poderosa do que isto.

Subconjuntos de vetores

Podemos extrair elementos selecionados de um vetor com um número de índice ou com um vetor de índices:

v <- 5:10
v
#> [1]  5  6  7  8  9 10
v[3] 
#> [1] 7
v[c(2, 4)]
#> [1] 6 8

Em alternativa, usa um vetor lógico para filtrar o vetor original, devolvendo um subconjunto de elementos que correspondem a um valor TRUE:

v <- 1:3
bools <- c(FALSE, TRUE, TRUE)
v[bools]
#> [1] 2 3

Daí até gerar o vetor de Boolean com uma expressão condicional é um pequeno passo:

bools <- v >= 2
bools
#> [1] FALSE  TRUE  TRUE

v[bools]
#> [1] 2 3

# simpler form
v[v >= 2]
#> [1] 2 3

Estas expressões condicionais podem ser arbitrariamente complexas, envolvendo vários vetores ou funções:

v <- 1:10
w <- 10:1

# pairwise comparison
v > w
#> [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

# shorter form
v[v > w]
#> [1]  6  7  8  9 10

Nomenclatura

Chamámos a este conceito Filtragem de Vetores, na esperança de que faça sentido para o maior número possível de programadores.

Dentro da comunidade de R, o termo «Subsetting» é provavelmente mais comum.

Reciclagem

Para simplificar, os exemplos acima comparavam todos vetores com o mesmo comprimento. O que acontece se os comprimentos não coincidirem?

A resposta é algo poderoso se for usado de forma deliberada, mas confuso se for inesperado.

Um exemplo:

v <- 1:6
cond <- c(TRUE, FALSE)
v[cond]
#> [1] 1 3 5

O que aconteceu ali? Indexámos um vetor de comprimento 6 com um Boolean de comprimento 2, mas obtivemos um vetor de comprimento 3 como resultado.

Se um vetor for demasiado «curto» para a expressão em que é usado, o R repete-o até se atingir o comprimento desejado: a isso chama-se «reciclagem». Isto transformou o nosso vetor c(TRUE, FALSE) em c(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE), e v[cond] devolveu então os valores TRUE de v: neste caso, os números ímpares.

Então o que acontece no exemplo seguinte?

v <- 1:3
0.5 * v
#> [1] 0.5 1.0 1.5
2 + v
#> [1] 3 4 5

À primeira vista, parece uma multiplicação escalar e uma adição escalar (um pouco estranha), mas não existem escalares no R.

Em vez disso, os números são reciclados para formar um vetor com o mesmo comprimento que v, e depois a operação aritmética é aplicada elemento a elemento, usando c(0.5, 0.5, 0.5) ou c(2, 2, 2).

Caution

A reciclagem é muito, muito útil, mas certifica-te de que é mesmo isto que pretendes.

Uma pequena diferença nos comprimentos dos vetores (por exemplo, 99 em vez de 100) pode causar bugs difíceis de perceber.

Alguns autores recomendam que a reciclagem só seja usada quando um dos vetores tem comprimento 1.

Encontrar índices

A função which() recebe um argumento Boolean e devolve um vetor de índices que dão TRUE.

v
#> [1] 2 7 9

v[v > 5]  # returns values
#> [1]  7  9

which(v > 5) # returns indices
#> [1] 2 3

Verificar se um elemento existe

As secções anteriores eram sobre encontrar elementos que cumprem um determinado critério.

Se só precisas de saber se o vetor contém um elemento específico, usa-se o operador %in%.

3 %in% 1:5
#> [1] TRUE
7 %in% 1:5
#> [1] FALSE

Isto é funcionalmente equivalente ao código seguinte, mas muito mais prático:

length(v[v == 3]) > 0
#> [1] TRUE

Existe também um operador %notin%, que dá o not lógico de %in%.

Editar via GitHub A ligação abre numa nova janela ou separador

Aprende Filtragem de vetores

A prática está bloqueada

Desbloqueia mais 2 exercícios para praticares Filtragem de vetores