Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
| — | 02_tutoriais:tutorial4:start [2025/09/02 19:11] (atual) – criada - edição externa 127.0.0.1 | ||
|---|---|---|---|
| Linha 1: | Linha 1: | ||
| + | <WRAP tabs> | ||
| + | * [[02_tutoriais: | ||
| + | * [[01_curso_atual: | ||
| + | * [[03_apostila: | ||
| + | </ | ||
| + | ====== 4. Tutoriais de Análise Exploratória de Dados ====== | ||
| + | |||
| + | Antes de iniciar uma análise propriamente dita, precisamos conhecer os dados e avaliar problemas com relação às etapas anteriores da pesquisa (coleta, processamento, | ||
| + | |||
| + | Dentre os principais **objetivos** de uma Análise Exploratória de Dados (AED) podemos listar os seguintes: | ||
| + | |||
| + | * Detectar erros nos dados; | ||
| + | * Detectar valores extremos (// | ||
| + | * Compreender a estrutura dos dados coletados; | ||
| + | * Indicar a melhor distribuição para modelar a variabilidade nos dados; | ||
| + | * Avaliar preliminarmente se os dados apresentam dependência/ | ||
| + | * Avaliar se variáveis preditoras apresentam colinearidade; | ||
| + | |||
| + | Não é objetivo deste tutorial passar por todos esses tópicos e sim, apresentar algumas técnicas da linguagem R para auxiliá-lo a iniciar as análises exploratória dos dados. Essas técnicas passam por duas instrumentações básicas: análise numérica com estatísticas descritivas e análises gráficas, explorando a variabilidade das variáveis e sua relação com outras variáveis. | ||
| + | |||
| + | |||
| + | |||
| + | ===== Conferindo Data Frames ===== | ||
| + | |||
| + | Após a leitura dos dados no R é uma boa prática verificá-lo cuidadosamente e investigar as variáveis em busca de erros e incoerências. Nesse tutorial iremos explorar algumas das ferramentas básicas para explorar dados de variáveis. | ||
| + | <WRAP center round box 80%> | ||
| + | |||
| + | [[http:// | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | Nesta sessão apresentamos duas situações bem comuns: variáveis de fatores com códigos errados e valores '' | ||
| + | |||
| + | Vamos usar uma planilha com dados fictícios de um estudo de [[: | ||
| + | |||
| + | Vamos ler o arquivo de texto contendo os dados com o '' | ||
| + | |||
| + | <code rsplus> | ||
| + | aves <- read.table(" | ||
| + | </ | ||
| + | |||
| + | Logo após a leitura, garanta que os dados foram lidos corretamente, | ||
| + | |||
| + | Verificação inicial do // data frame// | ||
| + | <code rsplus> | ||
| + | str(aves) | ||
| + | head(aves) | ||
| + | tail(aves) | ||
| + | |||
| + | </ | ||
| + | |||
| + | Com isso já temos um diagnóstico de um possível problema: os '' | ||
| + | Verificando as informações coletadas em campo descobrimos que esses campos são observações em que não houve avistamento da ave. Portanto, o valor correto é zero ((o problema inverso é comum e mais difícil de diagnosticar: | ||
| + | |||
| + | |||
| + | ==== Manipulando NA ==== | ||
| + | |||
| + | Vamos indexar para verificar onde estão esses '' | ||
| + | |||
| + | <code rsplus> | ||
| + | aves$urubu | ||
| + | aves$urubu == NA | ||
| + | </ | ||
| + | |||
| + | O teste lógico para '' | ||
| + | |||
| + | |||
| + | <code rsplus> | ||
| + | is.na(aves$urubu) | ||
| + | which(is.na(aves$urubu)) | ||
| + | </ | ||
| + | |||
| + | O '' | ||
| + | |||
| + | <code rsplus> | ||
| + | aves[is.na(aves$urubu), | ||
| + | aves$fisionomia[is.na(aves$urubu)] | ||
| + | </ | ||
| + | |||
| + | É possível também operar vários vetores lógicos para retornar os '' | ||
| + | |||
| + | <code rsplus> | ||
| + | is.na(aves$urubu) | is.na(aves$carcara) | ||
| + | </ | ||
| + | |||
| + | Acima o teste lógico com '' | ||
| + | |||
| + | <code rsplus> | ||
| + | aves[is.na(aves$urubu) | is.na(aves$carcara) | is.na(aves$seriema), | ||
| + | </ | ||
| + | |||
| + | Se indexarmos o objeto '' | ||
| + | Vamos guardar esses registros em um objeto, atribuindo o resultado do código acima a um objeto: | ||
| + | |||
| + | <code rsplus> | ||
| + | avesNAs <- aves[is.na(aves$urubu) | is.na(aves$carcara) | is.na(aves$seriema), | ||
| + | </ | ||
| + | |||
| + | Agora vamos sobrescrever os '' | ||
| + | |||
| + | <code rsplus> | ||
| + | aves$urubu[is.na(aves$urubu)] | ||
| + | aves$urubu[is.na(aves$urubu)] <- 0 | ||
| + | </ | ||
| + | |||
| + | Fizemos para a variável '' | ||
| + | |||
| + | |||
| + | <code rsplus> | ||
| + | is.na(aves) | ||
| + | aves[is.na(aves)] | ||
| + | aves[is.na(aves)] <- 0 | ||
| + | </ | ||
| + | |||
| + | Para garantir que fizemos a substituição corretamente, | ||
| + | |||
| + | <code rsplus> | ||
| + | aves[aves$urubu == 0 | aves$carcara == 0 | aves$seriema == 0, ] | ||
| + | avesNAs | ||
| + | </ | ||
| + | |||
| + | ==== Conferindo Fatores ==== | ||
| + | |||
| + | As variáveis categóricas ou fatores podem ser conferidas com as funções '' | ||
| + | |||
| + | |||
| + | <code rsplus> | ||
| + | unique(aves$fisionomia) | ||
| + | table(aves$fisionomia) | ||
| + | </ | ||
| + | |||
| + | O nível '' | ||
| + | |||
| + | <code rsplus> | ||
| + | aves$fisionomia == " | ||
| + | aves[aves$fisionomia == " | ||
| + | aves$fisionomia[aves$fisionomia == " | ||
| + | aves$fisionomia[aves$fisionomia == " | ||
| + | table(aves$fisionomia) | ||
| + | </ | ||
| + | |||
| + | |||
| + | Vamos agora converter esse vetor de caracteres para fator, ordenando as fisionomias da mais aberta para a mais fechada: | ||
| + | |||
| + | <code rsplus> | ||
| + | aves$fisionomia <- factor(aves$fisionomia, | ||
| + | </ | ||
| + | |||
| + | Sempre é bom verificar novamente para ver se a estruturação e os valores do objeto estão corretos: | ||
| + | |||
| + | <code rsplus> | ||
| + | str(aves) | ||
| + | </ | ||
| + | Agora parece que tudo está correto! | ||
| + | ===== Estatística Descritiva ===== | ||
| + | |||
| + | Vamos usar o mesmo arquivo da sessão anterior para explorar as estatísticas descritivas básicas, começando pela média e pela mediana. Nós já usamos o '' | ||
| + | |||
| + | |||
| + | <code rsplus> | ||
| + | apply(X = aves[ ,2:4], MARGIN = 2, FUN = mean) | ||
| + | apply(aves[ , | ||
| + | </ | ||
| + | |||
| + | O que significaria a média ser muito diferente da mediana? A mediana é pouco sensível aos valores extremos e mais sensível à assimetria da distribuição do que a média. | ||
| + | |||
| + | Podemos também fazer uma média truncada, usando o argumento '' | ||
| + | |||
| + | <code rsplus> | ||
| + | apply(aves[ , -1], 2, mean, trim = 0.1) | ||
| + | </ | ||
| + | |||
| + | O '' | ||
| + | |||
| + | Os quantis também são uma forma de verificar se a distribuição dos valores é simétrica. O padrão da função '' | ||
| + | <code rsplus> | ||
| + | quantile(aves$urubu) | ||
| + | summary(aves$urubu) | ||
| + | </ | ||
| + | |||
| + | O argumento '' | ||
| + | |||
| + | <code rsplus> | ||
| + | quantile(aves$urubu, | ||
| + | </ | ||
| + | |||
| + | A função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | summary(aves[ ,-1]) | ||
| + | </ | ||
| + | |||
| + | ===== Gráficos Univariados ====== | ||
| + | |||
| + | Os gráficos são ferramentas importantes para avaliarmos as variáveis dos nossos dados. No tópico de gráficos vamos estudar mais a fundo as funções associadas a elaboração de gráficos no R, por enquanto vamos apenas aplicar algumas funções básicas sem nos preocuparmos muito com o acabamento dos gráficos. Normalmente a análise exploratória de dados é introspectiva, | ||
| + | Vejamos alguns gráficos básicos de diagnóstico de uma variável numérica, usando como exemplo o avistamento de urubus no Cerrado: | ||
| + | |||
| + | /* | ||
| + | |||
| + | <code rsplus> | ||
| + | caixeta <- read.table(" | ||
| + | |||
| + | </ | ||
| + | */ | ||
| + | ==== Diagrama de Caixas ==== | ||
| + | |||
| + | O diagrama de caixas (boxplot) é a representação gráfica dos quartis que a função '' | ||
| + | |||
| + | <WRAP center round box 80%> | ||
| + | {{ : | ||
| + | |||
| + | </ | ||
| + | |||
| + | <code rsplus> | ||
| + | boxplot(aves$urubu) | ||
| + | </ | ||
| + | |||
| + | ==== Histograma e Gráfico de Barras ==== | ||
| + | |||
| + | Os histogramas são usados para representar a frequência absoluta (contagem) ou densidade de variáveis contínuas e os gráficos de barras para variáveis categóricas ou discretas. Abaixo construímos as duas formas, mas antes repartimos nossa janela gráfica em quatro porções utilizando a função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | par(mfrow = c(2, 2)) | ||
| + | barplot(table(aves$urubu)) | ||
| + | hist(aves$urubu) | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | O formato dos gráficos é muito diferente. Isso se deve ao fato do histograma agrupar as observações em intervalos, geralmente regulares. O número de intervalos vai influenciar muito o formato do gráfico, o R usa o algoritmo padrão da função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | hist(aves$urub, | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | Vamos usar a função '' | ||
| + | |||
| + | |||
| + | <code rsplus> | ||
| + | stripchart(aves$urubu, | ||
| + | par(mfrow = c(1, 1)) | ||
| + | </ | ||
| + | |||
| + | |||
| + | No código abaixo incluímos os principais gráficos diagnósticos em uma única janela: | ||
| + | |||
| + | |||
| + | |||
| + | <code rsplus> | ||
| + | par(mfrow = c(2, 2)) | ||
| + | boxplot(aves$urubu) | ||
| + | hist(aves$urubu) | ||
| + | barplot(table(aves$urubu)) | ||
| + | stripchart(aves$urubu, | ||
| + | par(mfrow = c(1, 1)) | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | ==== Comparações com distribuições teóricas ==== | ||
| + | |||
| + | Vamos agora retornar aos dados reais de [[dados: | ||
| + | |||
| + | <code rsplus> | ||
| + | caixeta <- read.table(file = " | ||
| + | summary(caixeta$cap) | ||
| + | par(mfrow = c(1, 2)) | ||
| + | hist(caixeta$cap) | ||
| + | boxplot(caixeta$cap) | ||
| + | par(mfrow = c(1, 1)) | ||
| + | </ | ||
| + | |||
| + | Essa distribuição de valores não parece nada com uma distribuição normal. Parece muito assimétrica com os dados concentrados nos valores menores. Além disso, tem uma longa cauda para os valores maiores. Várias características desses dados levam a uma distribuição como essa, as principais são: | ||
| + | * o '' | ||
| + | * a estrutura de tamanho de populações estáveis de plantas tem a tendência a ter uma distribuição como essa de '' | ||
| + | |||
| + | Uma forma de avaliar o acoplamento de um variável a uma distribuição normal é através dos gráficos '' | ||
| + | |||
| + | <code rsplus> | ||
| + | qqnorm(caixeta$cap) | ||
| + | qqline(caixeta$cap) | ||
| + | </ | ||
| + | |||
| + | Uma outra forma de fazer essa comparação é com o histograma de densidade, com o argumento '' | ||
| + | |||
| + | <code rsplus> | ||
| + | hist(caixeta$cap, | ||
| + | curve(dnorm(x, | ||
| + | </ | ||
| + | |||
| + | Para resolver o problema de distribuição de valores assimétricos e positivos é muito comum utilizar a transformação '' | ||
| + | |||
| + | <code rsplus> | ||
| + | par(mfrow = c(1, 2)) | ||
| + | hist(caixeta$cap, | ||
| + | curve(dnorm(x, | ||
| + | hist(log(caixeta$cap), | ||
| + | curve(dnorm(x, | ||
| + | par(mfrow = c(1, 1)) | ||
| + | </ | ||
| + | |||
| + | Parece que a transformação logarítmica ajudou no acoplamento da variável à distribuição normal. | ||
| + | |||
| + | <WRAP center round box 90%> | ||
| + | |||
| + | [[https:// | ||
| + | |||
| + | </ | ||
| + | |||
| + | /* | ||
| + | ===== Exploração de uma Variável Categórica ===== | ||
| + | Vamos usar um conjunto de dados de um inventário de árvores, que você pode baixar [[: | ||
| + | |||
| + | Vamos explorar a variável categórica nome da espécie, com a função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | caixeta <- read.csv(" | ||
| + | names(caixeta) | ||
| + | table(caixeta$especie) | ||
| + | </ | ||
| + | Qual a diferença no resultado se usamos o comando abaixo? | ||
| + | <code rsplus> | ||
| + | sort(table(caixeta$especie), | ||
| + | </ | ||
| + | |||
| + | O resultado da função '' | ||
| + | <code rsplus> | ||
| + | barplot(sort(table(caixeta$especie), | ||
| + | barplot(table(caixeta$local)) | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | ===== Variações do Histograma ===== | ||
| + | Voltando ao objeto criado no tutorial [[: | ||
| + | Você pode acrescentar marcas (traços) indicando a posição de cada observação no eixo x. | ||
| + | <code rsplus> | ||
| + | ## Histograma com os valores (função rug) | ||
| + | hist(aves.c$urubu) | ||
| + | rug(jitter(aves.c$urubu)) | ||
| + | </ | ||
| + | O que acontece se você omite a função '' | ||
| + | |||
| + | Agora vamos fazer um histograma re-escalonado de modo que as áreas das barras somem um. Com isto, podemos sobrepor ao histograma um ajuste não paramétrico de densidade probabilística, | ||
| + | |||
| + | <code rsplus> | ||
| + | hist(aves.c$urubu, | ||
| + | lines( density(aves.c$urubu), | ||
| + | </ | ||
| + | |||
| + | Também sobre este histograma podemos sobrepor a curva normal. Para os parâmetros da normal, usamos a média e o desvio-padrão da amostra. | ||
| + | <code rsplus> | ||
| + | hist(aves.c$urubu, | ||
| + | curve(expr = dnorm(x, mean = mean(aves.c$urubu), | ||
| + | </ | ||
| + | |||
| + | Por fim, vamos sobrepor a curva empírica de densidade probabilística com a curva normal: | ||
| + | <code rsplus> | ||
| + | plot(density(aves.c$urubu), | ||
| + | curve(expr = dnorm(x, mean = mean(aves.c$urubu), | ||
| + | </ | ||
| + | |||
| + | O que estes gráficos revelam sobre a distribuição do número de avistamentos de urubus neste estudo fictício? | ||
| + | */ | ||
| + | ===== Análise exploratória Bivariada ===== | ||
| + | |||
| + | A relação entre duas ou mais variáveis categóricas pode ser explorada com tabelas cruzadas, por exemplo: | ||
| + | |||
| + | <code rsplus> | ||
| + | table(caixeta$especie, | ||
| + | </ | ||
| + | |||
| + | |||
| + | Quando temos uma variável categórica (fator) e uma numérica, as funções '' | ||
| + | |||
| + | A função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | |||
| + | caixetaH <- aggregate(caixeta$h, | ||
| + | |||
| + | </ | ||
| + | |||
| + | A função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | str(caixetaH) | ||
| + | </ | ||
| + | |||
| + | A função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | caixAlt <- tapply(caixeta$h, | ||
| + | str(caixAlt) | ||
| + | class(caixAlt) | ||
| + | </ | ||
| + | |||
| + | <code rsplus> | ||
| + | dim(caixetaH) | ||
| + | dim(caixAlt) | ||
| + | </ | ||
| + | |||
| + | Os dados originais continha 1027 observações, | ||
| + | No primeiro caso nós temos 3 variáveis: '' | ||
| + | |||
| + | |||
| + | |||
| + | Consulte a ajuda da função '' | ||
| + | |||
| + | /* | ||
| + | ===== xtabs ===== | ||
| + | Crie um objeto com este [[: | ||
| + | <code rsplus> | ||
| + | xtabs(Freq~Sex+Survived, | ||
| + | prop.table(xtabs(Freq~Sex+Survived, | ||
| + | xtabs(Freq~Class+Survived, | ||
| + | prop.table(xtabs(Freq~Class+Survived, | ||
| + | </ | ||
| + | |||
| + | Por que usamos a função '' | ||
| + | <code rsplus> | ||
| + | table(Titanic.df$Sex, | ||
| + | </ | ||
| + | */ | ||
| + | ===== Gráficos Bivariados ===== | ||
| + | |||
| + | O gráfico de dispersão nos permite avaliar a relação entre duas variáveis numéricas: | ||
| + | |||
| + | <code rsplus> | ||
| + | plot(x = caixeta$cap, | ||
| + | </ | ||
| + | |||
| + | |||
| + | A função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | str(aves) | ||
| + | pairs(aves[ , c(" | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | A notação de fórmula estatística do R, usa o símbolo '' | ||
| + | |||
| + | <code rsplus> | ||
| + | fun(y ~ x, data = dados) | ||
| + | </ | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | Esta notação foi criada para os modelos estatísticos, | ||
| + | |||
| + | |||
| + | <code rsplus> | ||
| + | plot(h ~ cap, data = caixeta) | ||
| + | plot(h ~ cap, data = caixeta, subset = local == " | ||
| + | </ | ||
| + | |||
| + | A notação em fórmula nos gráficos tornam o código mais sintético e permitem algumas formulações interessantes, | ||
| + | |||
| + | <code rsplus> | ||
| + | boxplot(cap ~ local, data = caixeta) | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | Esta fórmula pode ainda incluir um fator condicionante, | ||
| + | |||
| + | |||
| + | <code rsplus> | ||
| + | fun(y ~ x | z, data = dados) | ||
| + | </ | ||
| + | * '' | ||
| + | |||
| + | O pacote '' | ||
| + | |||
| + | <code rsplus> | ||
| + | library(lattice) | ||
| + | xyplot(h ~ cap | local, data = caixeta) | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== O quarteto de Anscombe ===== | ||
| + | |||
| + | O pacote '' | ||
| + | |||
| + | <code rsplus> | ||
| + | str(anscombe) | ||
| + | |||
| + | </ | ||
| + | |||
| + | Este objeto é composto de 4 pares de variáveis, nomeadas '' | ||
| + | <code rsplus> | ||
| + | names(anscombe) | ||
| + | </ | ||
| + | |||
| + | Compare as médias de cada uma das variáveis. Para isto, use a função '' | ||
| + | <code rsplus> | ||
| + | apply(anscombe[1: | ||
| + | apply(anscombe[5: | ||
| + | </ | ||
| + | |||
| + | Faça o mesmo para obter as variâncias: | ||
| + | |||
| + | <code rsplus> | ||
| + | apply(anscombe[1: | ||
| + | apply(anscombe[5: | ||
| + | </ | ||
| + | |||
| + | A pergunta principal para este conjunto de dados é se há relação entre cada variável '' | ||
| + | |||
| + | <code rsplus> | ||
| + | cor(anscombe$x1, | ||
| + | </ | ||
| + | |||
| + | O código acima pode ser aplicado através da função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | with(anscombe, | ||
| + | with(anscombe, | ||
| + | with(anscombe, | ||
| + | with(anscombe, | ||
| + | </ | ||
| + | |||
| + | Uma outra forma de avaliar a relação é através dos coeficientes da reta de um modelo linear entre as duas variáveis. Essa relação é obtida pela função '' | ||
| + | |||
| + | <code rsplus> | ||
| + | (coef1 <- coef(lm(y1 ~ x1, data = anscombe))) | ||
| + | (coef2 <- coef(lm(y2 ~ x2, data = anscombe))) | ||
| + | (coef3 <- coef(lm(y3 ~ x3, data = anscombe))) | ||
| + | (coef4 <- coef(lm(y4 ~ x4, data = anscombe))) | ||
| + | </ | ||
| + | |||
| + | Perceba que todos os coeficientes estão muito próximos a '' | ||
| + | Vamos fazer os gráficos de dispersão entre as variáveis '' | ||
| + | |||
| + | |||
| + | /* | ||
| + | <code rsplus> | ||
| + | par(mfrow = c(2, 2)) # 4 graficos em uma janela | ||
| + | plot(y1 ~ x1, data = anscombe) | ||
| + | plot(y2 ~ x2, data = anscombe) | ||
| + | plot(y3 ~ x3, data = anscombe) | ||
| + | plot(y4 ~ x4, data = anscombe) | ||
| + | par(mfrow = c(1, 1)) | ||
| + | </ | ||
| + | */ | ||
| + | |||
| + | <code rsplus> | ||
| + | par(mfrow = c(2, 2)) # 4 graficos em uma janela | ||
| + | plot(y1 ~ x1, data = anscombe, | ||
| + | xlim = range(anscombe[, | ||
| + | abline(coef1) | ||
| + | plot(y2 ~ x2, data = anscombe, | ||
| + | xlim = range(anscombe[, | ||
| + | abline(coef2) | ||
| + | plot(y3 ~ x3, data = anscombe, | ||
| + | xlim = range(anscombe[, | ||
| + | abline(coef3) | ||
| + | plot(y4 ~ x4, data = anscombe, | ||
| + | xlim = range(anscombe[, | ||
| + | abline(coef4) | ||
| + | par(mfrow=c(1, | ||
| + | </ | ||
| + | |||
| + | Este conjunto de dados foi criado pelo estatístico Frank Anscombe para demonstrar a importância da análise visual de dados (veja mais detalhes [[http:// | ||
| + | |||
| + | ===== Leia mais sobre análise exploratória de dados ===== | ||
| + | |||
| + | |||
| + | Artigo com um protocolo de análise exploratória de dados: | ||
| + | *[[http:// | ||
| + | |||
| + | Capítulo do livro " | ||
| + | *{{: | ||
| + | |||