11.1 Tem valores ausentes?

Há valores ausentes em nossos dados? Eles são mesmo faltantes? Ou seja, o que significam valores ausentes no seu conjunto de dados?

Podemos utilizar a função is.na() para encontrar a constante lógica NA, ou seja, a constante que indica valores ausentes (reveja o uso da função is.na() na seção 2.6.3). Vejam o ? da constante lógica NA para entender o significado dela no R:

?NA

Continuemos de onde paramos na seção anterior. Vimos que há a presença de NA no data.frame avesc. Chequemos quais registros (linhas) têm valores NA. Vamos checar primeiramanete a variável avesc$urubu:

avesc$urubu == NA ## erro: não retorna verdadeiro ou falso
avesc[avesc$urubu == NA, ] ## também não funciona

Reparem que os comandos acima, apesar de funcionarem, não respondem à nossa pergunta que é saber quais linhas possuem NA. Para isso, devemos nos valer da função is.na():

is.na(avesc) # pergunta em todo o data frame: quem é NA?
fisionomia urubu carcara seriema
Ce1 FALSE FALSE FALSE FALSE
Ce2 FALSE FALSE FALSE FALSE
Ce3 FALSE FALSE FALSE FALSE
Ce4 FALSE FALSE FALSE FALSE
Ce5 FALSE FALSE FALSE FALSE
Ce6 FALSE TRUE FALSE TRUE
Ce7 FALSE FALSE FALSE FALSE
Ce8 FALSE FALSE FALSE FALSE
Ce9 FALSE FALSE FALSE FALSE
Ce10 FALSE FALSE FALSE FALSE
Ce11 FALSE FALSE FALSE FALSE
Ce12 FALSE FALSE FALSE FALSE
Ce13 FALSE FALSE FALSE FALSE
Ce14 FALSE FALSE FALSE FALSE
Ce15 FALSE FALSE FALSE FALSE
Ce16 FALSE FALSE FALSE FALSE
Ce17 FALSE FALSE FALSE FALSE
Ce18 FALSE FALSE FALSE FALSE
Ce19 FALSE FALSE FALSE FALSE
Ce20 FALSE FALSE FALSE FALSE
CC1 FALSE FALSE FALSE FALSE
CC2 FALSE FALSE FALSE FALSE
CC3 FALSE FALSE FALSE FALSE
CC4 FALSE FALSE FALSE FALSE
CC5 FALSE FALSE FALSE TRUE
CC6 FALSE FALSE FALSE FALSE
CC7 FALSE FALSE FALSE FALSE
CC8 FALSE FALSE FALSE FALSE
CC9 FALSE FALSE FALSE FALSE
CC10 FALSE FALSE FALSE FALSE
CC11 FALSE FALSE FALSE FALSE
CC12 FALSE FALSE FALSE FALSE
CC13 FALSE FALSE FALSE FALSE
CC14 FALSE FALSE FALSE FALSE
CC15 FALSE FALSE FALSE FALSE
CC16 FALSE FALSE FALSE FALSE
CC17 FALSE FALSE FALSE FALSE
CC18 FALSE FALSE FALSE FALSE
CC19 FALSE FALSE FALSE FALSE
CC20 FALSE FALSE FALSE FALSE
CL1 FALSE FALSE FALSE FALSE
CL2 FALSE FALSE FALSE FALSE
CL3 FALSE FALSE FALSE FALSE
CL4 FALSE FALSE FALSE FALSE
CL5 FALSE FALSE FALSE FALSE
CL6 FALSE FALSE FALSE FALSE
CL7 FALSE FALSE FALSE FALSE
CL8 FALSE FALSE FALSE FALSE
CL9 FALSE FALSE TRUE FALSE
CL10 FALSE FALSE FALSE FALSE
CL11 FALSE FALSE FALSE FALSE
CL12 FALSE FALSE FALSE FALSE
CL13 FALSE FALSE FALSE FALSE
CL14 FALSE FALSE FALSE FALSE
CL15 FALSE FALSE FALSE FALSE
CL16 FALSE FALSE FALSE FALSE
CL17 FALSE FALSE FALSE FALSE
CL18 FALSE FALSE FALSE FALSE
CL19 FALSE FALSE FALSE FALSE
CL20 FALSE FALSE FALSE FALSE
!is.na(avesc) # inverte: quem não é NA?
fisionomia urubu carcara seriema
Ce1 TRUE TRUE TRUE TRUE
Ce2 TRUE TRUE TRUE TRUE
Ce3 TRUE TRUE TRUE TRUE
Ce4 TRUE TRUE TRUE TRUE
Ce5 TRUE TRUE TRUE TRUE
Ce6 TRUE FALSE TRUE FALSE
Ce7 TRUE TRUE TRUE TRUE
Ce8 TRUE TRUE TRUE TRUE
Ce9 TRUE TRUE TRUE TRUE
Ce10 TRUE TRUE TRUE TRUE
Ce11 TRUE TRUE TRUE TRUE
Ce12 TRUE TRUE TRUE TRUE
Ce13 TRUE TRUE TRUE TRUE
Ce14 TRUE TRUE TRUE TRUE
Ce15 TRUE TRUE TRUE TRUE
Ce16 TRUE TRUE TRUE TRUE
Ce17 TRUE TRUE TRUE TRUE
Ce18 TRUE TRUE TRUE TRUE
Ce19 TRUE TRUE TRUE TRUE
Ce20 TRUE TRUE TRUE TRUE
CC1 TRUE TRUE TRUE TRUE
CC2 TRUE TRUE TRUE TRUE
CC3 TRUE TRUE TRUE TRUE
CC4 TRUE TRUE TRUE TRUE
CC5 TRUE TRUE TRUE FALSE
CC6 TRUE TRUE TRUE TRUE
CC7 TRUE TRUE TRUE TRUE
CC8 TRUE TRUE TRUE TRUE
CC9 TRUE TRUE TRUE TRUE
CC10 TRUE TRUE TRUE TRUE
CC11 TRUE TRUE TRUE TRUE
CC12 TRUE TRUE TRUE TRUE
CC13 TRUE TRUE TRUE TRUE
CC14 TRUE TRUE TRUE TRUE
CC15 TRUE TRUE TRUE TRUE
CC16 TRUE TRUE TRUE TRUE
CC17 TRUE TRUE TRUE TRUE
CC18 TRUE TRUE TRUE TRUE
CC19 TRUE TRUE TRUE TRUE
CC20 TRUE TRUE TRUE TRUE
CL1 TRUE TRUE TRUE TRUE
CL2 TRUE TRUE TRUE TRUE
CL3 TRUE TRUE TRUE TRUE
CL4 TRUE TRUE TRUE TRUE
CL5 TRUE TRUE TRUE TRUE
CL6 TRUE TRUE TRUE TRUE
CL7 TRUE TRUE TRUE TRUE
CL8 TRUE TRUE TRUE TRUE
CL9 TRUE TRUE FALSE TRUE
CL10 TRUE TRUE TRUE TRUE
CL11 TRUE TRUE TRUE TRUE
CL12 TRUE TRUE TRUE TRUE
CL13 TRUE TRUE TRUE TRUE
CL14 TRUE TRUE TRUE TRUE
CL15 TRUE TRUE TRUE TRUE
CL16 TRUE TRUE TRUE TRUE
CL17 TRUE TRUE TRUE TRUE
CL18 TRUE TRUE TRUE TRUE
CL19 TRUE TRUE TRUE TRUE
CL20 TRUE TRUE TRUE TRUE
avesc[!is.na(avesc)]
##   [1] "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce"
##  [16] "Ce" "Ce" "ce" "Ce" "Ce" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC"
##  [31] "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CL" "CL" "CL" "CL" "CL"
##  [46] "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL"
##  [61] " 5" " 7" " 5" " 3" " 4" " 6" " 4" " 2" " 5" " 6" " 6" " 7" " 6" " 5" " 5"
##  [76] " 3" "13" " 8" " 7" "22" "10" "17" "16" "20" "18" "16" "14" "12" "15" " 9"
##  [91] "11" "20" "18" " 8" "15" "17" "17" "12" "12" "11" "10" "19" "15" "13" "12"
## [106] "16" "13" "19" "19" "11" "18" "15" "19" "13" "16" "10" "12" "18" "19" "18"
## [121] " 7" "14" "12" "16" "20" "19" "21" "11" " 9" "12" "24" "17" "16" "15" "12"
## [136] "14" "14" "21" "13" " 8" "16" "14" "16" "10" " 7" " 8" " 8" " 7" "14" "11"
## [151] "12" "11" "11" " 7" "14" " 8" "14" " 7" " 9" " 3" " 5" " 5" " 8" " 6" " 5"
## [166] " 5" " 3" " 5" " 3" " 3" " 6" " 4" " 4" " 5" " 3" " 6" " 5" " 4" " 6" " 6"
## [181] " 4" " 5" " 4" " 4" "10" " 6" " 7" " 8" " 5" " 6" " 4" " 6" " 8" " 3" " 4"
## [196] " 2" " 4" " 5" " 3" " 3" " 6" " 3" " 5" " 4" " 4" " 4" " 8" " 4" " 4" " 3"
## [211] " 6" " 5" " 5" " 6" " 6" "12" " 9" " 6" " 5" " 4" " 6" " 4" " 5" " 6" " 5"
## [226] " 4" " 9" " 7" " 5" " 4" " 6" " 2" "10" " 7" " 4" " 4"

Proceder com o último comando gera um resultado confuso, pois o data.frame é convertido em um vetor de dimensão de 236 valores. Podemos investigar da maneira abaixo. Checamos qual é o tamanho total de valores presentes no objeto avesc, multiplicando o número de linhas pelo número de colunas através da expressão (nrow(avesc) * ncol(avesc)). Temos então um número total de 240 valores possíveis em avesc. E comparamos essa valor com o número de valores não faltantes em avesc através da expressão length(avesc[!is.na(avesc)]), que retorna 236. Portanto, se não houver valores faltantes, a primeira expressão abaixo deve retornar verdadeiro (TRUE), e falso (FALSE) se houver valores faltantes:

(nrow(avesc) * ncol(avesc)) == length(avesc[!is.na(avesc)])
## [1] FALSE

Então quantos valores faltantes existem em nossos dados?

# ou então, o número de valores NA no data.frame é de:
(nrow(avesc) * ncol(avesc)) - length(avesc[!is.na(avesc)])
## [1] 4

O procedimento adotado acima pode ser difícil de entender. Fazer essa pergunta por colunas torna o entendimento mais fácil:

is.na(avesc$urubu) # quais são NA, vetor lógico
##  [1] FALSE FALSE FALSE FALSE FALSE  TRUE 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 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# mesmo que
is.na(avesc$urubu) == T
##  [1] FALSE FALSE FALSE FALSE FALSE  TRUE 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 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# e o contrário é (quem não é NA)
is.na(avesc$urubu) == F
##  [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [13]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [25]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [37]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [49]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
# ou simplesmente
!is.na(avesc$urubu)
##  [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [13]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [25]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [37]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [49]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

Vetores lógicos TRUE e FALSE podem ser somados. TRUE corresponde a 1, e FALSE a 0. Usando o resultado de is.na(avesc$urubu) (ou qualquer outra variável de avesc) junto à função sum(), teremos então o número de valores faltantes na variável escolhida:

sum(is.na(avesc$urubu)) # quantos sao?
## [1] 1
sum(!is.na(avesc$urubu)) # quantos não são?
## [1] 59
# e, isso é verdadeiro, né?
(sum(is.na(avesc$urubu)) + sum(!is.na(avesc$urubu))) == nrow(avesc)
## [1] TRUE

Podemos perguntar quais posições do vetor lógico oriundo de is.na(avesc$urubu) são correspondentes a NA por meio da função which(). Teremos como resposta um vetor de números inteiros indicando o número das linhas com valores NA na urubu:

which(is.na(avesc$urubu)) # vetor com indices das posições que são NA
## [1] 6

Vamos utilizar agora este resultado para filtrar o data.frame avesc e checar que linha é essa:

avesc[which(is.na(avesc$urubu)), ] # mesma coisa, mas precisa de uma segunda função, então menos parcimonioso
fisionomia urubu carcara seriema
Ce6 Ce NA 20 NA

Podemos filtrar também sem a função which(), usando apenas os vetores lógicos TRUE e FALSE oriundos da função is.na():

avesc[is.na(avesc$urubu), ] # mostra as linhas completas para os registros com NA na coluna urubu
fisionomia urubu carcara seriema
Ce6 Ce NA 20 NA
## para ver se tem NA em uma das tres colunas com nomes de aves: usamos o operador | (quer dizer 'ou')
meufiltro <- is.na(avesc$urubu) | is.na(avesc$carcara) | is.na(avesc$seriema)
sum(is.na(avesc)) # soma dos valores NA nas tres colunas
## [1] 4
avesc[meufiltro, ] # mostra todas as linhas que tem algum valor NA
fisionomia urubu carcara seriema
Ce6 Ce NA 20 NA
CC5 CC 20 10 NA
CL9 CL 19 NA 5
# Esses valores NA, na verdade são AUSENCIA da ave (não avistamento) numa determinada localidade (linha no dado). Portanto, NA neste caso deveria ser de fato 0.

## Então, vamos corrigir estes valores
vl <- is.na(avesc$urubu)
## Podemos ver os valores de vários jeitos
avesc$urubu[vl] # assim
## [1] NA
avesc[vl, "urubu"] # ou assim
## [1] NA
avesc[, "urubu"][vl] # ou assim...
## [1] NA
# se podemos ver, podemos atribuir 0 para esse valor ausentes
avesc$urubu[vl] <- 0

## Continuando, para as outras aves, mostrando variacoes de códigos
avesc$carcara[is.na(avesc$carcara)] <- 0
avesc$seriema[is.na(avesc$seriema) == T] <- 0

## Verificando se substituimos corretamente
avesc[meufiltro, ]
fisionomia urubu carcara seriema
Ce6 Ce 0 20 0
CC5 CC 20 10 0
CL9 CL 19 0 5
# poderiamos ter feito a mudanca de uma vez
aves2[meufiltro, ] # a cópia que fiz no início
fisionomia urubu carcara seriema
Ce6 Ce NA 20 NA
CC5 CC 20 10 NA
CL9 CL 19 NA 5
aves2[meufiltro, ][is.na(aves2[meufiltro, ])] # visualizo só os NAs
## [1] NA NA NA NA
aves2[meufiltro, ][is.na(aves2[meufiltro, ])] <- 0 # atribuo 0

## Agora esses valores são zero, certo?
avesc[avesc$urubu == 0 | avesc$carcara == 0 | avesc$seriema == 0, ]
fisionomia urubu carcara seriema
Ce6 Ce 0 20 0
CC5 CC 20 10 0
CL9 CL 19 0 5