Trilhas
/
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 em uma expressão condicional, gerando um vetor lógico. Isso, 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

A técnica é muito mais poderosa do que isso.

Subconjuntos de vetores

Podemos extrair elementos selecionados de um vetor com um número de índice ou 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

Como alternativa, use um vetor lógico para filtrar o vetor original, retornando um subconjunto de entradas associadas a um valor TRUE:

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

A partir daí é um passo pequeno para gerar o vetor Boolean com uma expressão condicional:

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

v[bools]
#> [1] 2 3

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

Essas 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

Chamamos este conceito de "Filtragem de Vetores", na esperança de que faça sentido para a maior variedade possível de programadores.

Na comunidade de R, o termo "Subsetting" provavelmente é mais comum.

Reciclagem

Por simplicidade, os exemplos acima comparavam sempre vetores do mesmo comprimento. O que acontece se os comprimentos forem diferentes?

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

Um exemplo:

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

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

Se um vetor for de alguma forma "curto demais" para a expressão em que é usado, o R vai repeti-lo até atingir o comprimento desejado: isso se chama "reciclagem". Isso transformou nosso vetor c(TRUE, FALSE) em c(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE), e v[cond] então retornou os valores TRUE de v: neste caso, os números ímpares.

Então o que está acontecendo no próximo exemplo?

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

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

Em vez disso, os números são reciclados para formar um vetor do mesmo comprimento de v, e então 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 verifique se é isso mesmo que você pretende.

Uma pequena diferença nos comprimentos dos vetores (por exemplo, 99 vs 100) pode causar bugs confusos.

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

Encontrando índices

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

v
#> [1] 2 7 9

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

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

Verificando se uma entrada existe

As seções anteriores tratavam de encontrar entradas que atendem a algum critério.

Se você só precisa 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

Isso é funcionalmente equivalente ao código a seguir, mas muito mais conveniente:

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

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

Editar via GitHub O link abre em uma nova janela ou aba

Aprenda Filtragem de vetores

A prática está bloqueada

Desbloqueie mais 2 exercícios para praticar Filtragem de vetores