2.6 Vetores e operadores lógicos
Para manipular dados no R, entender vetores lógicos e operadores lógicos é fundamental.
Vetores lógicos são vetores de verdadeiros (TRUE
ou apenas T
, sempre em letras maiúsculas) ou falsos (FALSE
ou F
).
Eles podem ser convertidos em vetores numéricos e, portanto, operados matematicamente (T
= 1, e F
= 0).
2.6.1 Fazendo perguntas à vetores
Vetores lógicos podem ser respostas às perguntas feitas por operadores lógicos:
>
- é maior que?<
- é menor que?>=
- é maior igual a?<=
- é menor igual a?==
- é igual a?!=
- é diferente de?%in%
- compara conteúdo de vetores
Há ainda a função duplicated()
que busca valores repetidos em um vetor.
O resultado desta função é um vetor contendo TRUE
ou FALSE
.
Valores que possuam o valor TRUE
são duplicados.
Para checar os duplicados, devemos filtrar o resultado desta ação (veja na seção 2.6.2).
# um vetor numerico
<- 1:20
v1 # quais valores de v1 são maiores ou iguais a 10
<- v1 >= 10 # vai retornar um vetor lógico
p1 p1
## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE
## [13] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
# soma dos verdadeiros responde "quantos valores de v1 são maiores ou iguais a 10, pois apenas esses valores são verdadeiros ou seja são 1)
sum(p1)
## [1] 11
# experimente os demais operadores
# a regra da reciclagem também se aplica neste conceito
<- 1:20
v1 <- 1:20
v2 <- v1 == v2 # compara cada par dos vetores que são idênticos
p2 # é o vetor lógico resultando, todos os valores são verdadeiros p2
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [16] TRUE TRUE TRUE TRUE TRUE
# portanto, as seguintes expressões também são verdadeiras
sum(v1 == v2) == length(v1)
## [1] TRUE
# ou então
sum(v1 == v2) == length(v2)
## [1] TRUE
# valores duplicados
<- c(2, 2, 2, 3, 4, 5)
vv # apenas o dois é duplicado vv
## [1] 2 2 2 3 4 5
duplicated(vv) # note que esta função retorna TRUE apenas para dois dos três valores 2 (o primeiro não é duplicado)
## [1] FALSE TRUE TRUE FALSE FALSE FALSE
# comparando vetores
<- c(1, 2, 3, 4)
v1 <- c(4, 4, 5, 6)
v2 %in% v2 # quantos elementos de v1 existem em v2 v1
## [1] FALSE FALSE FALSE TRUE
sum(v1 %in% v2) # apenas 1
## [1] 1
%in% v1 # quais elementos de v2 estão em v1 v2
## [1] TRUE TRUE FALSE FALSE
sum(v2 %in% v1) # os dois quatro
## [1] 2
<- c(6.0, 5.1, 6.8, 2.8, 6.1, 9.0, 4.3, 10.4, 6.0, 7.9, 8.9, 6.8, 9.8, 4.6, 11.3, 8.0, 6.7, 4.5)
notas.dos.alunos ## Quantos aprovados?
sum(notas.dos.alunos >= 5)
## [1] 14
# Qual a proporção de aprovados?
<- sum(notas.dos.alunos >= 5) / length(notas.dos.alunos)
prop prop
## [1] 0.7777778
# ou em texto
paste(round(prop * 100), "%", sep = "")
## [1] "78%"
Podemos usar também vetores de texto e fatores em conjunto com operadores lógicos.
# E VETORES DE TEXTO?
<- rep(c("banana", "pera", "laranja", "limão"), 10)
v1 # um vetor de palavras v1
## [1] "banana" "pera" "laranja" "limão" "banana" "pera" "laranja"
## [8] "limão" "banana" "pera" "laranja" "limão" "banana" "pera"
## [15] "laranja" "limão" "banana" "pera" "laranja" "limão" "banana"
## [22] "pera" "laranja" "limão" "banana" "pera" "laranja" "limão"
## [29] "banana" "pera" "laranja" "limão" "banana" "pera" "laranja"
## [36] "limão" "banana" "pera" "laranja" "limão"
# quantos elementos são iguais a banana
== "banana" v1
## [1] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
## [13] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
## [25] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
## [37] TRUE FALSE FALSE FALSE
sum(v1 == "banana")
## [1] 10
# também poderia perguntar: quantos elementos de v1 contém banana
sum(v1 %in% "banana")
## [1] 10
%in% "banana" v1
## [1] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
## [13] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
## [25] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
## [37] TRUE FALSE FALSE FALSE
# no caso acima == e %in% funcionam igual, mas o operador %in% é util quando quisermos comparar dois vetores de character
<- c("banana", "pera", "abacate")
v2 %in% v2 # quais elementos de v1 correspondem a elementos de v2 v1
## [1] TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE
## [13] TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE
## [25] TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE
## [37] TRUE TRUE FALSE FALSE
sum(v1 %in% v2) # quantos são? 10 laranjas e 10 peras
## [1] 20
%in% v1 # quais elementos de v2 estão em v1 v2
## [1] TRUE TRUE FALSE
sum(v2 %in% v1) # quantos são (apenas laranja e pera, abacate não está)
## [1] 2
Operadores auxiliares permitem combinar perguntas:
&
equivale aE
- essa condição E essa outra;|
equivale aOU
- essa condição OU essa outra;!
- inverte os valores da pergunta
# um vetor
<- 1:20
v1 v1
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<- v1 > 5 & v1 <= 15 # quais elementos de v1 são maiores que 5 E menores ou iguais a 15
p1 sum(p1) # quantos são?
## [1] 10
<- v1 > 5 | v1 <= 15 # quais elementos de v1 são maiores que 5 OU menores ou iguais a 15
p1 sum(p1) # quantos são
## [1] 20
# !exclamação NEGA ou INVERTE verdadeiros e falsos
<- 1:20
v1 sum(v1 == 5) # quantos v1 são iguais a 5?
## [1] 1
sum(!v1 == 5) # quantos v1 são diferentes de 5?
## [1] 19
sum(v1 > 5) # quantos v1 são maiores que 5?
## [1] 15
sum(!v1 > 5) # quantos v1 são menores que 5?
## [1] 5
# texto
<- rep(c("banana", "pera", "laranja", "limão"), 10)
v1 # um vetor de palavras v1
## [1] "banana" "pera" "laranja" "limão" "banana" "pera" "laranja"
## [8] "limão" "banana" "pera" "laranja" "limão" "banana" "pera"
## [15] "laranja" "limão" "banana" "pera" "laranja" "limão" "banana"
## [22] "pera" "laranja" "limão" "banana" "pera" "laranja" "limão"
## [29] "banana" "pera" "laranja" "limão" "banana" "pera" "laranja"
## [36] "limão" "banana" "pera" "laranja" "limão"
<- v1 == "banana" & v1 == "pera" # quantos elementos de v1 sao banana E sao pera
vl vl
## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [37] FALSE FALSE FALSE FALSE
sum(vl) # nenhum valor satisfaz as duas condicoes
## [1] 0
<- v1 == "banana" | v1 == "pera" # quantos elementos de v1 sao banana ou sao pera
vl vl
## [1] TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE
## [13] TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE
## [25] TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE
## [37] TRUE TRUE FALSE FALSE
sum(vl) # tem 20 valores que satisfazem 1 das condições
## [1] 20
# isso é o mesmo que pergunta desse outro jeito:
sum(v1 %in% c("banana", "pera"))
## [1] 20
2.6.2 Filtrando dados com vetores lógicos
Vetores lógicos podem ser usados como índices (Seção 2.5) para filtrar elementos de um vetor. É através deste conceito que podemos filtrar dados de matrizes e criar subconjunto de dados.
# um vetor com sequencia de 1 a 100
<- 1:100
v1
<- v1 > 15 # Pergunta 1 quantos são maiores que 15
p1 # valores que satisfazem a pergunta 1 v1[p1]
## [1] 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
## [20] 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
## [39] 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
## [58] 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
## [77] 92 93 94 95 96 97 98 99 100
<- v1 <= 20 # Pergunta 2 quantos são menores ou iguais a 20
p2 # valores que satisfazem a pergunta 2 v1[p2]
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# quantos satisfazem as duas perguntas
<- p1 & p2
p3 # valores que satisfazem as duas perguntas v1[p2]
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
A função grep()
permite a busca de uma palavra (ou pedaço dela) em um vetor de palavras.
Mais de uma palavra pode ser buscada ao mesmo tempo.
# veja o help dessa função e seus argumentos ?grep
# um vetor de palavras
<- rep(c("banana", "pera", "laranja", "limão"), 5)
v1 grep("an", v1) # quais elementos tem a palavra 'an' no nome?
## [1] 1 3 5 7 9 11 13 15 17 19
# note que é case.sensitive (depende se é maiusculo ou minúsculo)
grep("An", v1) # não encontra nada
## integer(0)
grep("An", v1, ignore.case = T) # mas eu posso dizer para ele ignorar se é minusculo ou maiúsculo e ele encontra novamente
## [1] 1 3 5 7 9 11 13 15 17 19
# quem sao esses elementos
<- grep("An", v1, ignore.case = T) # pega os índices desses elementos
vl v1[vl]
## [1] "banana" "laranja" "banana" "laranja" "banana" "laranja" "banana"
## [8] "laranja" "banana" "laranja"
unique(v1[vl]) # valores únicos desse vetor
## [1] "banana" "laranja"
2.6.3 Perguntando por valores ausentes - NA
Vimos anteriormente como o R codifica valores ausentes (seção 1.8.4): converte em uma classe lógica definida pela palavra NA
em maiúsculo.
E nossos dados frequentemente têm valores ausentes.
Isso vai gerar avisos indesejáveis e impedir certas análises.
Então, muitas vezes precisamos tirar registros com valores ausentes ou colunas com muitos valores ausentes.
Perguntar por valores ausentes no R é feito por uma função especial chamada is.na()
.
A resposta da função é um vetor lógico indicando quem é e quem não é NA
.
Há uma outra função chamada na.omit()
que elimina valores NA
de um vetor.
# veja o help ?is.na
# um vetor com NAs
<- c(NA, NA, 1, 2, 3, 4, 5, 6)
v1 is.na(v1) # quem é NA?
## [1] TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
<- v1[!is.na(v1)] # criar um vetor novo com quem não é NA (note o !)
v2 v2
## [1] 1 2 3 4 5 6
# isso também pode ser feito com na.omit()
# veja o help dessa função ?na.omit
<- na.omit(v1)
v3 # a diferença é que criou um objeto de classe na.omit v3
## [1] 1 2 3 4 5 6
## attr(,"na.action")
## [1] 1 2
## attr(,"class")
## [1] "omit"
<- as.vector(v3) # isso elimina a diferença, convertendo em vetor
v3 # agora é idêntico a v2 v3
## [1] 1 2 3 4 5 6
# agora suponha o seguinte vetor
<- c("NA", "NA", "pera", "banana", "mamão")
v4 is.na(v4) # ops todos são falsos
## [1] FALSE FALSE FALSE FALSE FALSE
# isso porque "NA" é texto e não um objeto de classe lógica
class(NA)
## [1] "logical"
class("NA")
## [1] "character"
# mas eu poderia corrigir isso
== "NA"] # vejo v4[v4
## [1] "NA" "NA"
== "NA"] <- NA # corrijo
v4[v4 v4
## [1] NA NA "pera" "banana" "mamão"
is.na(v4) # agora dois são NAs
## [1] TRUE TRUE FALSE FALSE FALSE
# note que agora todos são diferentes de "NA" como texto
!v4 == "NA"] v4[
## [1] NA NA "pera" "banana" "mamão"
# mas isso de mostra quem não é corretamente
<- v4[!is.na(v4)]
v5 v5
## [1] "pera" "banana" "mamão"