• Fernanda Kelly

Valores ausentes?

Se você trabalha ou estuda utilizando dados, você sabe o quanto estes símbolos são recorrentes em nosso dia a dia e que, frequentemente, não sabemos como lidar com eles. Seja em um resumo estatístico, modelagem ou em gráficos. Sempre surge uma dúvida (ou várias): O que fazer com estes dados faltantes?


Em R, os valores ausentes ou faltantes são representados pelo símbolo NA que é uma constante lógica de comprimento 1, já os valores ditos "impossíveis" (por exemplo, divisão por zero) são representados pelo símbolo NaN (não um número). O R usa o mesmo símbolo tanto para caracteres quanto para dados numéricos, mas o NA do tipo de caractere é diferente da string "NA". Os programadores que precisam especificar uma string ausente explícita devem usar NA_character_ em vez de "NA", ou definir os elementos para NA usando is.na <-.


Mas como saber se há ou não missings na minha tabela de dados? No R, temos as funções originárias do pacote base que iniciam com is, e uma delas é a is.na (já citada ali acima). A função is.na <- pode fornecer uma maneira mais segura de definir a ausência de uma informação em seu vetor ou banco de dados. Veja nos exemplos abaixo três de suas aplicações: em caracteres, valores reais e fatores.


x <- c(NA,"A","B","C")
base::is.na(x) # retorna TRUE onde x é um missing

y <- c(1,2,3,NA)
base::is.na(y) # retorna um vetor do tipo (FALSE FALSE FALSE TRUE)

z <- c(1,NA,2,3)
as.factor(z)
base::is.na(z) # retorna um vetor do tipo (FALSE TRUE FALSE FALSE) 

Este método padrão para o is.na retorna em sua saída um vetor lógico (TRUE ou FALSE) de mesmo comprimento do argumento x (no caso do nosso exemplo), contendo TRUE para os elementos marcados como NA ou, para vetores numéricos ou complexos, NaN e FALSE caso contrário.


Existem também constantes NA_integer_, NA_real_, NA_complex_ e NA_character_ dos outros tipos de vetores que suportam valores ausentes. Note que NA_integer_ é da classe inteiro, NA_real_ é da classe numeric, e assim por diante.



class(NA_integer_)
[1] "integer"

x <- factor(sample(letters[1:5], 10, replace = TRUE))
if_else(x %in% c("a", "b", "c"), x, factor(NA))
if_else(TRUE, 1, NA_real_)

x <- sample(c("a", "b", "c", NA), 10, replace = TRUE)
recode(x, a = "Apple")
recode(x, a = "Apple", .default = NA_character_)
recode(x, a = "Apple", .default = NA_character_, .missing = "Unknown")


E qual é a importância dos valores NA? Em alguns casos, os componentes de um vetor podem não ser completamente conhecidos e esta é uma situação recorrente no trabalho com dados e quando um elemento ou valor "não está disponível" ou um "valor ausente" no sentido estatístico, um lugar dentro de um vetor pode ser reservado para ele atribuindo-lhe o valor especial NA.


E por que não excluir estes valores ausentes dado a sua irrelevância? Excluir estes valores ausentes é uma solução simplista, mas no caso de resumos estatísticos podemos "ocultar" estes das famosas análises descritivas. Já em casos de substituição por demais valores, outros métodos devem ser abordados para tal.


Algumas das funções que podem nos auxiliar em ocultar/omitir são: na.omit, na.action, na.fail e na.exclude. Estas funções lidam com vetores, matrizes e quadros de dados compreendendo vetores e matrizes (apenas), sendo estas derivadas do pacote stats do R.


Considere o seguinte exemplo (rode no R para melhor entendimento):

set.seed(1) #semente 
df <- data.frame(x=rnorm(100), y = rnorm(100))
df[sample(1:100,20),1] <- NA #aleatoriamente insira 20 NA's na coluna 1
df[sample(1:100,20),2] <- NA #aleatoriamente insira 20 NA's na coluna 2

A função na.omit remove as linhas que contém observações NA, em que o número de linhas dos casos NA formam o atributo "na.action" do resultado, da classe "omit".


df2 <- stats::na.omit(df)

Então o que difere o na.exclude do na.omit? Há diferença apenas na classe do atributo "na.action" do resultado, que passa a ser "exclude". Este comportamento é diferente quando estamos utilizando funções que fazem uso de naresid e napredict: quando na.exclude é usado, os resíduos e as previsões são preenchidos com o comprimento correto inserindo NA's para casos omitidos por na.exclude.


Quanto ao na.fail, este retorna o objeto se ele não contiver algum valor ausente e sinaliza um erro caso contrário.


na.fail(df)
## Erro em na.fail.default (df): valores ausentes no objeto

É válido ressaltar que qualquer operação em um NA torna-se um NA. A motivação para esta regra é simplesmente que, se a especificação de uma operação estiver incompleta, o resultado não pode ser conhecido e, portanto, não está disponível.


E diante de todas essas situações, eu só quero substituir os NA's por algum valor, como faço? Diante da imensidão de pacotes do R, um deles sempre chama atenção: O pacote Dplyr. Entre as diversas funções deste pacote maravilhoso, temos a função coalesce() que encontra o primeiro valor ausente em cada posição. Ele é inspirado na função SQL COALESCE que faz a mesma coisa para NULLs.


No próximo exemplo, a função coalesce() completa os valores NA do vetor z com os valores correspondentes de mesma posição i do vetor y.


y <- c(1, 2, 1, NA, 5)
z <- c(NA, NA, 3, 4, 5)

dplyr::coalesce(y, z) #completa um vetor com o outro no lugar do missing 

Já no exemplo abaixo, a função coalesce() substitui os valores NA's do vetor A por 0, mas se seu interesse é inserir NA's em observações cujo a informação se encontra vazia, basta utilizar a função na_if.


A <- c(1, NA, 1, NA, 0)
dplyr::coalesce(A,0)

A <- c(1, , 1, NA, 0)
dplyr::na_if(A, "")

E se você não souber por qual valor substituir seus valores NA? Como proceder?

Bem, este é um grande problema. Como estatística eu responderia que depende da sua questão de pesquisa, da sua variável, da modelagem de interesse ou problema de negócio. Talvez um valor ausente pode ser resolvido pela média ou mediana da variável, mas também podemos estimar este valor via bootstrap, por exemplo. Por isso, depende.


Há vários pacotes que atuam com essa ideia de bootstrap para missings values, e um deles é o pacote Amelia. Este pacote (Amelia II) tem o nome de Amelia Earhart, a primeira aviadora mulher a voar sozinha pelo Oceano Atlântico. A história diz que ela desapareceu misteriosamente (desaparecida) enquanto voava sobre o oceano Pacífico em 1937, portanto, este pacote foi nomeado para resolver problemas de valores ausentes.


Amelia II é um pacote para a imputação múltipla de dados incompletos multivariados. Ele usa um algoritmo que combina bootstrapping e o algoritmo EM para extrair dados posteriores dos dados ausentes. O pacote Amelia inclui transformações de normalização, antecedentes em nível de célula e métodos para lidar com dados de seção transversal de série temporal. O pacote também generaliza abordagens existentes, permitindo tendências em séries temporais em observações dentro de uma unidade transversal, bem como antecedentes que permitem que os pesquisadores incorporem as crenças que possuem sobre os valores das células ausentes em seus dados. O Amelia II também inclui diagnósticos úteis do ajuste de vários modelos de imputação.


#Amelia requer R versão 2.14.0 ou superior.

#Instalação manual
install.packages ( " Amelia " )

#Instalando a versão instável do desenvolvedor:
require(devtools)
install_github("IQSS/Amelia", ref = "develop")

Entendeu o por que não é tão fácil essa substituição?

Continue os estudos sobre valores ausentes por aí e conta pra gente as novidades ou o que já sabe nos comentários.


Até mais!


Fernanda Kelly R. Silva | Fundadora R-Ladies GYN






Posts recentes

Ver tudo