alt text

GET00130 - Métodos Computacionais para Estatística II

Jony Arrais Pinto Junior

Conteúdo da aula

  • Estimação pontual (medidas descritivas);
  • Tabelas de distribuição de frequência;
  • ggplot2.

1 - Análise exploratória de dados

Com o intuito de identificar padrões nos dados coletados, iremos apresentar como obter estimativas pontuais, que servem para resumir os dados, no R.

Para apresentar como calcular as medidas de interesse, vamos inicialmente importar o conjunto de dados que será utilizado nos exemplos.

Atividade: Importe o arquivo Base saude.csv e armazene-o em um objeto chamado base_saude O número 9 foi utilizado como um código para identificar dados faltantes em todas as variáveis.

#Visualizando o objeto
base_saude
# A tibble: 200 x 10
   Codigo Datacol   Sexo Idade  Peso Estatura   HIV Escol   DST  Tipo
   <chr>  <chr>    <dbl> <dbl> <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl>
 1 AB01   14/10/15     1    15  65.4     1.62     1     3     1     2
 2 AB02   09/02/16     0    28  60.4     1.55     0     5     0    NA
 3 AB03   01/03/10     0    15  87.6     1.89     1     2     1     3
 4 AB04   04/05/13     0    13  86.3     1.94     1    NA     1     2
 5 AB05   20/05/14     0    19  81.2     1.65     0     2     1     3
 6 AB06   30/01/11     1    14  77.2     1.66     1     6     0    NA
 7 AB07   05/08/15     1    25  63.4     1.59     1     5     1     3
 8 AB08   08/12/13     1    26  73.2     1.59     0     1     0     2
 9 AB09   03/11/10     1    35  63.1     1.64     1     4     1     1
10 AB10   10/10/10     1    37  58.7     1.56     1     5     1    NA
# … with 190 more rows

Tratando as variáveis qualitativas da base de dados.

#Transformando a variável Sexo em um factor
base_saude$Sexo = factor(x = base_saude$Sexo,
                         labels = c("Feminino","Masculino"))

#Transformando a variável HIV em um factor
base_saude$HIV = factor(x = base_saude$HIV, 
                        labels = c("Não","Sim"))

#Transformando a variável Escolaridade em um ordered
base_saude$Escol = ordered(x = base_saude$Escol,
                           levels = c(0,1,2,3,4,5), 
                           labels = c("Analfabeto","Fundamental Incompleto","Fundamental Completo","Medio Incompleto", "Medio Completo","Superior"))

#Transformando a variável DST em um factor
base_saude$DST = factor(x = base_saude$DST, 
                        labels = c("Não","Sim"))

#Transformando a variável Tipo de DST em um factor
base_saude$Tipo = factor(x = base_saude$Tipo, 
                         labels = c("Sifilis","Hepatite","Outros"))

1.1 - Tabela de distribuição de frequências

Uma tabela de distribuição de frequências é uma tabela contendo as(os) categorias(valores) ou agrupamento das categorias(valores) de uma determinada variável. Podemos apresentar as frequências absolutas, percentuais e acumuladas.

Vamos construir tabelas de distribuição de frequência no R usando o pacote expss.

Inicialmente, vamos ver como aplicar rótulo as variáveis com este pacote, isto é, quando formos acessar uma variável no objeto base_saude ela continua com o seu nome (de maneira geral, curto e simples) e no momento em que a tabela for apresentada, ela apresentará o rótulo indexado aquela variável.

Para realizarmos esta tarefa, usamos a função apply_labels.

#Ativando o pacote expss
library(expss)

#Acrescentando rótulos nos nomes das variáveis
base_saude = apply_labels(base_saude,
                      Codigo = "Matricula paciente",
                      Datacol = "Data da coleta",
                      Sexo = "Gênero",
                      Idade = "Idade",
                      Peso = "Peso (em Kg)",
                      Estatura = "Altura (em cm)",
                      HIV = "Possui HIV",
                      Escol = "Escolaridade",
                      DST = "DST",
                      Tipo = "Tipo de DST"
)

Após executarmos o código, nada irá acontecer, o resultado será visto quando criarmos as tabelas usando o pacote expess.

Para obtermos uma tabela de distribuição de frequências contendo a frequência absoluta (Count), o percentual válido (Valid percent), o percentual (Percent) e o percentual acumulado (Cumulative responses, % ) usamos a função fre. A diferença entre a coluna Valid percent e Percent, é que a primeira é calculada desconsiderando os NA.

#Tabela de distribuição de frequência para uma variável
base_saude |> 
  select(Escol) |> 
  fre()
Escolaridade  Count   Valid percent   Percent   Responses, %   Cumulative responses, % 
 Analfabeto  13 8.8 6.5 8.8 8.8
 Fundamental Incompleto  32 21.6 16.0 21.6 30.4
 Fundamental Completo  34 23.0 17.0 23.0 53.4
 Medio Incompleto  13 8.8 6.5 8.8 62.2
 Medio Completo  30 20.3 15.0 20.3 82.4
 Superior  26 17.6 13.0 17.6 100.0
 #Total  148 100 74 100
 <NA>  52 26.0

Agora, se quisermos obter uma tabela de contingência, ou também conhecida como tabela de dupla entrada, contendo as frequências absolutas, usaremos a função calc_cro_cases, com os percentuais calculados por coluna (somando 100% em cada coluna) usaremos a função calc_cro_cpct e com os percentuais calculados por linha (somando 100% em cada linha) usaremos a função calc_cro_rpct.

#Tabela de contingência frequência absoluta
base_saude |> 
  calc_cro_cases(Escol,HIV)
 Possui HIV 
 Não   Sim 
 Escolaridade 
   Analfabeto  13
   Fundamental Incompleto  14 18
   Fundamental Completo  21 13
   Medio Incompleto  1 12
   Medio Completo  13 16
   Superior  13 13
   #Total cases  62 85
#Tabela de contingência percentual por coluna
base_saude |> 
  calc_cro_cpct(Escol,HIV)
 Possui HIV 
 Não   Sim 
 Escolaridade 
   Analfabeto  15.3
   Fundamental Incompleto  22.6 21.2
   Fundamental Completo  33.9 15.3
   Medio Incompleto  1.6 14.1
   Medio Completo  21.0 18.8
   Superior  21.0 15.3
   #Total cases  62 85
#Tabela de contingência percentual por linha
base_saude |> 
  calc_cro_rpct(Escol,HIV)
 Possui HIV 
 Não   Sim 
 Escolaridade 
   Analfabeto  100.0
   Fundamental Incompleto  43.8 56.2
   Fundamental Completo  61.8 38.2
   Medio Incompleto  7.7 92.3
   Medio Completo  44.8 55.2
   Superior  50.0 50.0
   #Total cases  62 85

1.2 - Medidas de posição (medidas de tendência central)

São medidas resumos que servem como representantes numéricos para o conjunto de dados, as vezes são calculadas considerando todos os dados disponíveis, as vezes parte dos dados disponíveis.

Principais medidas de tendência central: média, moda, mediana, quantis, entre outras.

Para obtermos estimativas pontuais destas medidas podemos usar funções apropriadas.

Suponha que queremos obter diversas medidas de tendência central para a variável Idade para os que possuem HIV e para os que não possuem HIV.

#obtendo as medidas de posição discutidas para a variável 
#idade para os grupos de HIV, desconsiderando os indivíduos
#cuja informação do status do HIV era desconhecido

base_saude |>
  filter(!is.na(HIV)) |> 
  group_by(HIV) |> 
  summarise(media = mean(Idade, na.rm = TRUE),
            mediana = median(Idade, na.rm = TRUE),
            quartil1 = quantile(Idade, probs = .25, na.rm = TRUE))
# A tibble: 2 x 4
  HIV   media mediana quartil1  
  <fct> <dbl>   <dbl> <labelled>
1 Não    24.2      23 19        
2 Sim    24.2      23 19        

O uso do na.rm = TRUE é justficado pela necessidade de se excluir os valores faltantes da variável idade para o cálculo das medidas. Caso exista um indivíduo que não é portador do HIV com idade não registrada, todas as medidas referentes ao grupo HIV = Não seriam apresentadas como NA, a menos que utilizemos a o argumento na.rm = TRUE.

1.3 - Medidas de dispersão

O resumo do conjunto de dados por uma única medida representativa de posição central esconde toda a informação sobre a heterogeneidade do conjunto de observações. As medidas de dispersão trazem informações sobre o grau de homogeneidade dos dados.

Principais medidas de dispersão: variância, desvio padrão, desvio absoluto mediano, coeficiente de variação, entre outras.

#obtendo as medidas de dispersão discutidas para a variável 
#idade para os grupos de HIV, desconsiderando os indivíduos
#cuja informação do status do HIV era desconhecido

base_saude |>
  filter(!is.na(HIV)) |> 
  group_by(HIV) |> 
  summarise(variancia = var(Idade, na.rm = TRUE),
            desvio = sd(Idade, na.rm = TRUE),
            dam = mad(Idade, na.rm = TRUE),
            CV = desvio/mean(Idade, na.rm = TRUE)*100)
# A tibble: 2 x 5
  HIV   variancia desvio   dam    CV
  <fct>     <dbl>  <dbl> <dbl> <dbl>
1 Não        43.9   6.63  5.93  27.4
2 Sim        53.6   7.32  8.90  30.3

2 - ggplot2

alt text

Hadley Wickham, junto com demais colaboradoes, criaram o ggplot2 com o intuíto de fornercer uma ferramenta capaz de fornecer um “modelo poderoso para a produção de gráficos complexos de múltiplas camadas”.

alt text

Vantagens do ggplot2

  • Gramática de gráficos consistente;
  • especificação de plotagem em um alto nível de abstração;
  • muito flexível;
  • Sistema de tema para polir a aparência do gráfico;
  • sistema gráfico completo e maduro;
  • muitos usuários, lista de discussão ativa.

Dito isto, existem algumas coisas que você não pode (ou não deve) fazer com o ggplot2:

  • Gráficos tridimensionais (veja o pacote RGL);
  • Gráficos de tipos de teoria de grafos (veja o pacote igraph);
  • Gráficos interativos (veja o pacote ggvis).

Qual é gramática dos gráficos?

Idéia básica: especificar separadamente blocos de construção de plotagem e combiná-los para criar qualquer tipo de exibição gráfica que você deseja.

Os blocos de construção de um gráfico incluem:

  • dados;
  • mapeamento estético;
  • objeto geométrico;
  • transformações estatísticas;
  • escalas;
  • sistema de coordenadas;
  • ajustes de posição;
  • facetas;

A estrutura básica de código para criar um ggplot é a seguinte:


ggplot(data = meu_data_frame, mapping = aes(x, y)) + geom()


Primeiro criamos um plot com a função ggplot. O primeiro argumento é o data, onde você especifica o data frame com suas variáveis. Depois vem o mapping. Nele você cria o “mapeamento” das variáveis, normalmente usando aes (de aesthetics), ou seja, você especifica dentre várias coisas, por exemplo, quais são as variáveis que serão representadas nos eixos x e y, cores e símbolos usados para plotar os dados.

Depois da função ggplot, nós especificamos um geom. Por exemplo, geom_point para plotar pontos, geom_boxplot para um boxplot, etc. Para a lista completa de geoms e todas as outras opções do pacote, visite a página do projeto ggplot2.

Note que adicionamos um geom com um “+”. No ggplot2, nós criamos gráficos em camadas (layers), e adicionamos camada a camada com um “+”.

ggplot2 VS Gráficos básicos

Comparado ggplot2 com os gráficos usuais:

  • é mais complicado para gráficos simples;
  • é menos complicado para gráficos complexos:
  • não tem métodos definidos (exemplo, os dados devem estar sempre em um formato tibble);
  • usa um sistema diferente para adicionar elementos ao gráfico.

Atividade: Importe o arquivo PNUD.csv e armazene-o em um objeto chamado base_PNUD.

A base de dados possui variáveis referentes aos municípios brasileiros, nos anos 1991, 2000 e 2010, tais como:

  • ano;
  • nome do município (muni);
  • uidade da federação (uf);
  • região (regiao);
  • índice de desenvolvimento humano e seus componentes (idhm, idhm_e, idhm_l, idhm_r);
  • expectativa de vida (expvida);
  • renda per capta (rpdc);
  • índice de gini (gini);
  • tamanho da população (pop);
  • cordenadas de latitude e longitude do centróide do município (lat e lon).
#Visualizando o objeto
base_PNUD
# A tibble: 16,694 x 14
     ano muni  uf    regiao  idhm idhm_e idhm_l idhm_r expvida  rdpc  gini   pop
   <dbl> <chr> <chr> <chr>  <dbl>  <dbl>  <dbl>  <dbl>   <dbl> <dbl> <dbl> <dbl>
 1  1991 ALTA… RO    Norte  0.329  0.112  0.617  0.516    62.0 198.   0.63 22835
 2  1991 ARIQ… RO    Norte  0.432  0.199  0.684  0.593    66.0 319.   0.57 55018
 3  1991 CABI… RO    Norte  0.309  0.108  0.636  0.43     63.2 116.   0.7   5846
 4  1991 CACO… RO    Norte  0.407  0.171  0.667  0.593    65.0 320.   0.66 66534
 5  1991 CERE… RO    Norte  0.386  0.167  0.629  0.547    62.7 240.   0.6  19030
 6  1991 COLO… RO    Norte  0.376  0.151  0.658  0.536    64.5 225.   0.62 25070
 7  1991 CORU… RO    Norte  0.203  0.039  0.572  0.373    59.3  81.4  0.59 10737
 8  1991 COST… RO    Norte  0.425  0.22   0.629  0.553    62.8 250.   0.65  6902
 9  1991 ESPI… RO    Norte  0.388  0.159  0.653  0.561    64.2 263.   0.63 22505
10  1991 GUAJ… RO    Norte  0.468  0.247  0.662  0.625    64.7 391.   0.6  31240
# … with 16,684 more rows, and 2 more variables: lat <dbl>, lon <dbl>

Vamos comparar abaixo os códigos para produzirmos um gráfico de dispersão das variáveis renda per capta e índice de gini no ano de 2010. Para elaborar este gráfico, iremos usar a função ggplot e geom_point (esta segunda é a responsável por fazer o gráfico de pontos, isto é, o gráfico é definido em função do geom_ que escolhemos).

#Gráfico de dispersão da renda per capta e do índice de GINI para o ano de 2010
plot(base_PNUD$rdpc[base_PNUD$ano==2010], base_PNUD$gini[base_PNUD$ano==2010])

#Gráfico de dispersão da renda per capta e do índice de GINI para o ano de 2010 usando ggplot2
base_PNUD |> 
  filter(ano == 2010) |> 
  ggplot(mapping = aes(x = rdpc, y = gini)) + 
  geom_point()

Neste gráfico indicamos no aesthetics (aes) quais variáveis seriam apresentadas no eixo x e no eixo y.

Podemos perceber que o gráfico produzido pelo ggplot2 possui uma estética mais interessante do que o gráfico produzido pelas funções básicas do R, mas não é só isso. Veremos a seguir que o pacote nos permite elaborar gráficos mais complexos de forma mais simples.

Suponha que pretendessemos indicar no gráfico a qual região cada ponto pertence.

# Indicando a qual região o ponto pertence
graf1 = base_PNUD |> 
  filter(ano == 2010) |> 
  ggplot(mapping = aes(x = rdpc, 
                       y = gini, 
                       color = regiao)) +
  geom_point()

#Visualizando o objeto
graf1

No gráfico acima indicamos no aesthetics (aes) quais variáveis seriam apresentadas no eixo x e no eixo y e que a cor dos pontos seria definida em função das categorias da variável região. Poderia ser utilizado em color uma variável quantitativa.

Outro ponto que vale a pena chamarmos atenção é que os gráficos no ggplot podem ser armazenados em objetos e depois modificados.

Atividade: Faça um gráfico de dispersão entre as variáveis renda per capta e índice de gini e que a cor de cada ponto reflita o valor da expectativa de vida dos municípios.

Suponha que nosso interesse seja implementar algumas melhorias no gráfico, como modificar os rótulos dos eixos e o título da legenda. Basta usarmos a função labs. No labs foi utilizado o argumento colour porque a legenda do gráfico foi criada definindo um colour no aes, caso fosse outro argumento, o mesmo deveria ser usado no labs.

#Modificando os rótulos dos eixos
graf1 +
  labs(x = "Renda per capta",
       y = "Índice de gini",
       colour = "Região")

Suponha que desejamos comparar o índice de gini das grandes regiões do Brasil no ano de 2010 por meio de um boxplot. Para criarmos esse novo gráfico precisaremos trabalhar com um novo geom, o geom_boxplot.

# Boxplot do Índice de GINI por região no ano de 2010
graf2 = base_PNUD |> 
  filter(ano == 2010) |> 
  ggplot(mapping = aes(x = regiao, 
                       y = gini)) + 
  geom_boxplot() +
  labs(x = "Região", 
       y = "Índice de Gini")

#Visualizando o objeto
graf2

Suponha que foi solicitado a inclusão dos valores das medianas nos boxplot. Como faremos isso?

Podemos incialmente obter esses valores usando as funções group_by e summarise.

# Calculando as medianas do índice de gini para cada região no ano de 2010
medianas = base_PNUD |> 
  filter(ano == 2010) |> 
  group_by(regiao) |> 
  summarise(val.med = median(gini, na.rm = TRUE))

#Visualizando o objeto
medianas
# A tibble: 5 × 2
  regiao       val.med
  <chr>          <dbl>
1 Centro-Oeste    0.49
2 Nordeste        0.52
3 Norte           0.56
4 Sudeste         0.46
5 Sul             0.46

Para incluir os valores no gráfico, basta usarmos a função annotate.

Principais argumentos da função annotate:

  - x - coordenda x do local onde será inserido o texto;

  - y - coordenda y do local onde será inserido o texto;

  - label - o texto que será inserido na coordenada (x,y) especificada;

  - color - a cor do texto a ser plotado;

  - vjust - o valor da perturbação a ser feita na vertical;

  - size - o tamanho do texto a ser plotado.

# Refazendo o boxplot anterior cada um com uma cor diferente
graf2 +
  annotate("text",
           x = medianas$regiao,
           y = medianas$val.med,
           label = medianas$val.med,
           color ="red", 
           vjust = -.2, 
           size = 4)

É possível fazer algumas modificações na estética do gráfico (características gerais), gerenciando seus temas (layouts). Vamos experimentar alguns dos temas abaixo. Para plotar vários gráficos em uma mesma figura podemos usar a função grid.arrange do pacote gridExtra.

Exemplos de temas existentes:

  • theme_gray() (default),
  • theme_bw(),
  • theme_linedraw(),
  • theme_light(),
  • theme_minimal(),
  • theme_classic(),
  • theme_void().
#Carregando pacote para plotar mais de um gráfico numa mesma figura
library(gridExtra)

#Modificando os temas do gráfico 2
tema1 = graf2 +
  theme_classic()

tema2 = graf2 +
  theme_minimal()

tema3 = graf2 +
  theme_light()

tema4 = graf2 +
  theme_linedraw()


#Plotando todos os gráficos em uma mesma figura
grid.arrange(tema1, tema2, tema3, tema4, ncol = 2, nrow = 2)

Para criarmos um gráfico de barras, basta usarmos o geom_bar.

#Criando gráfico de barras para o número de municípios por regiões em 2010
base_PNUD |> 
  filter(ano == 2010) |> 
  ggplot(mapping = aes(x = regiao)) + 
  geom_bar(fill = "blue")

No gráfico acima indicamos no aesthetics (aes) qual variável seria apresentada no eixo x somente. Se usarmos o fill com uma cor no geom_bar fora do aes, modificamos a cor do gráfico de barra.

Se o nosso desejo for criar gráficos para tabelas de contingência, podemos fazer isso usando o geom_bar e fazendo uma pequena modificação no aes.

#Região x Índice de Gini (categorizada)
grafb1 = base_PNUD |> 
  filter(ano == 2010) |>
  mutate(gini_cat = cut(gini, breaks = c(0,0.5,0.6,1), labels = c("Alto","Médio","Baixo"))) |> 
  ggplot(mapping = aes(x = regiao, fill = gini_cat)) + 
  geom_bar() +
  labs(x = "Região",
       y = "Frequência",
       fill = "Índice de Gini")

#Região x Índice de Gini (categorizada)
grafb2 = base_PNUD |> 
  filter(ano == 2010) |>
  mutate(gini_cat = cut(gini, breaks = c(0,0.5,0.6,1), labels = c("Alto","Médio","Baixo"))) |> 
  ggplot(mapping = aes(x = regiao, fill = gini_cat)) + 
  geom_bar(position = "dodge") +
  labs(x = "Região",
       y = "Frequência",
       fill = "Índice de Gini") +
  coord_flip()

#Região x Índice de Gini (categorizada)
grafb3 = base_PNUD |> 
  filter(ano == 2010) |>
  mutate(gini_cat = cut(gini, breaks = c(0,0.5,0.6,1), labels = c("Alto","Médio","Baixo"))) |> 
  ggplot(mapping = aes(x = regiao, fill = gini_cat)) + 
  geom_bar(position = "fill") +
  labs(x = "Região",
       y = "Frequência",
       fill = "Índice de Gini")

#Plotando todos os gráficos em uma mesma figura
grid.arrange(grafb1, grafb2, grafb3, ncol = 2, nrow = 2)

Para a criação dos três gráficos acima foi criado uma variável que categorizava o índice de gini em 3 categorias (Baixo, Médio e Alto). As diferenças entre os gráficos residem se as barras são sobrepostas, ou paralelas e se os eixos quando são paralelas se referem a frequências relativas.

O argumento position definiu a diferença entre os 3 gráficos.

O coord_flip seviu para invertermos as coordenadas de um gráfico que já estava pronto, isto é, o que definimos para o eixo y foi representado no eixo x e vice-versa.

Se quisermos mudar a escala do gráfico grafb3 basta usarmos a função scale_y_continuous.

# Mudando a escala do gráfico
grafb3 +
  scale_y_continuous(labels = scales::percent_format()) 

Se querem mais facilidades do pacote ggplot2 vejam abaixo.

#Criando a variável populoso
base_PNUD = base_PNUD |>
  mutate(populoso = cut(x = pop,
                       breaks = c(0,8000,20000,Inf),
                       labels = c("Não","Intermediário","Sim")))

#Criando o gráfico para todos os anos
graf3 = base_PNUD |> 
  ggplot(aes(x = rdpc, y = gini,color = regiao)) + 
  geom_point() +
  labs(x = "Renda per capta", 
       y = "Índice de Gini",
       color = "Região")

graf3

#Particionando graf3 por ano
graf3 + 
  facet_wrap(~ ano)

#Particionando graf3 por ano e por populoso
graf3 + 
  facet_grid(populoso ~ ano)

As funções facet_wrap e facet_grid fatiam gráficos em função de outras variáveis sem que seja necessário recriar o gráfico para cada subgrupo de interesse.