Tutorial 6: Intro ao Tidyverse: Manipulação de Banco de Dados

Introdução.

Nas nossas duas primeiras semanas de aula, focamos em uma introdução básica ao R e sobre como comunicar nossos resultados usando relatórios dinâmicos e de alta qualidade via RMarkdown.

No decorrer das próximas três semanas, focaremos em três habilidades centrais para nosso trabalho em ciência de dados: i) manipulação de banco de dados, b) visualização de dados, e c) programação funcional.

Para aprender estas três habilidades, faremos amplo uso dos pacotes do tidyverse.

Tidyverse

O tidyverse é uma família de pacotes em R. Estes pacotes foram e são desenvolvidos de forma integrada, compartilhando uma mesma filosofia de design, gramática e estruturas de dados subjacentes. Portanto, se você aprender um, os outros pacotes ficarão mais fáceis.

O objetivo do tidyverse é prover um conjunto integrado de ferramentas para o uso do R para tarefas de ciência de dados. O que signifca que os pacotes do tidyverse cobrem temas variados como manipulação de dados, visualização, preparação, modelagem, limpeza, entre outros. Estes são os principais pacotes do tidyverse:

  • dplyr: para manipulação de dados.

  • ggplot2: para visualização de dados.

  • tidyr: para preparar seus dados para análise.

  • purrr: para otimizar seu código e para programação funcional.

  • readr: para abrir e organizar os dados.

  • stringr: para manipulação de objetos de texto.

  • forcats: para manipulação da classe fatores.

Porque devo usar o tidyverse ?

Você não deve usar o tidyverse. Porém, há diversas vantagens para sua dinâmica de trabalho em R em usar os pacotes do tidyverse. Algumas delas são:

  • O tidyverse integra diversos pacotes em um. Ao fim, você precisa instalar um pacote para fazer basicamente tudo em R.

  • O tidyverse facilita substancialmente as tarefas de análise de dados quando comparado com códigos do R básico.

  • Aumenta substancialmente quão legível seu código parece.

  • Manipulação, visualização e modelagem estão integradas no tidyverse.

  • É amplamente utilizado na comunidade de R. Portanto, provavelmente você irá se deparar com códigos escritos no estilo tidyverse no futuro.

No tutorial de hoje, faremos uma breve introdução ao tidyverse e em seguida focaremos no uso do do dplyr para manipulação de bancos de dados.

Entrando no Tidyverse

Instalação.

O primeiro passo é instalarmos o tidyverse. Com um comando, estamos instalando dezenas de pacotes em nosso R.

install.packages("tidyverse")
library(tidyverse)

Tibbles.

O objeto fundamental do tidyverse são bancos de dados. Sendo um pacote desenvolvido para ciência de dados, todos os pacotes do tidyverse são desenvolvidos para funcionar com banco de dados como sua estrutura de dados fundamental.

O tidyverse usa objetos da classe “tibbles” para definir seus bancos de dados ao invés do tradicional data.frame, que aprendemos semana passada. Tibbles são exatamente iguais a banco de dados em sua estrutura básica, no entanto, tibbles possuem alguns ajustes para facilitar sua aplicabilidade e visualização.

Criando Tibbles.

# Classe do Banco de Dados mtcars
class(mtcars)
## [1] "data.frame"
# Converte para tibbles
mtcars_tib <- as_tibble(mtcars)
mtcars_tib
## # A tibble: 32 x 11
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
##  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
##  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
##  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
##  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
##  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
##  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
##  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
##  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
## 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
## # … with 22 more rows

Pipe.

knitr::include_graphics("figs/pipe.jpg")

O uso de pipes %>% é uma peça fundamental no funcionamento dos pacotes do tidyverse, em particular para processos de manipulação de bancos de dados.

O %>%permite a você concatenar, conectar em cadeias as funções do seu código. Esta conexão faz com que nossos códigos se tornem mais intuitivos e fáceis de serem lidos e interpretados.

Para entendermos a utilidade dos pipes, é bom perceber primeiro como o R conecta operações distintas.

O R base funciona de dentro para fora:

# R
x <- c(1:10)
round(exp(sqrt(mean(x))), 1)
## [1] 10.4

o %>% conecta estas operações em ordem lógica:

x %>%
  mean() %>%
  sqrt() %>%
  exp() %>%
  round(1) 
## [1] 10.4

Notas importantes sobre os pipes.

1. Os pipes sempre devem ser usados para conectar funções e seus outputs.

# Não rode este código.
x %>%
  funcao1(arg1=x) %>%
  funcao2(arg=output_da_funcao1)

Exemplo:

sample(1:1000, 500, replace=TRUE) %>%
  density() %>% # funcao 1.
  plot() # função 2. 

2. O input sempre pode ser omitido, ou representados pelo atalho .

sample(1:1000, 500, replace=TRUE) %>%
  density(.) %>% # funcao 1.
  plot(.) # função 2. 

3. Os resultados do pipe não são salvos imediatamente. Você precisa atribuir à um novo objeto.

grafico <- sample(1:1000, 500, replace=TRUE) %>%
              density(.) %>% # funcao 1.
              plot(.) # função 2. 

Desafio.

Reescreva o código abaixo utilizando o %>%.

library(tidyverse)

x <- "cpdoc"
x <- str_to_upper(x)
x <- str_c(x, "-FGV")
x <- str_to_title(x)
x
## [1] "Cpdoc-Fgv"

Manipulação de dados com dplyr.

A partir deste ponto, focaremos no pacote dplyr para manipular e transformar banco de dados. Em nossos exemplo, vamos utilizar dados eleitorais do Brasil, extraídos a partir do pacote cepespR.

Dados Eleitorais: cepespR

if (!require("devtools")) install.packages("devtools")
devtools::install_github("Cepesp-Fgv/cepesp-r") 
library(cepespR)
library(tidyverse)

pres_rio <- get_votes(year = 2018, 
                      position = "Presidente", 
                      regional_aggregation = "Municipio", 
                      state="RJ") %>%
                  as_tibble()

Informações básicas

glimpse(pres_rio)
## Rows: 1,374
## Columns: 19
## $ ANO_ELEICAO       <int> 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 201…
## $ SIGLA_UE          <chr> "BR", "BR", "BR", "BR", "BR", "BR", "BR", "BR", "BR…
## $ NUM_TURNO         <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ DESCRICAO_ELEICAO <chr> "ELEIÇÃO GERAL FEDERAL 2018", "ELEIÇÃO GERAL FEDERA…
## $ CODIGO_CARGO      <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ DESCRICAO_CARGO   <chr> "PRESIDENTE", "PRESIDENTE", "PRESIDENTE", "PRESIDEN…
## $ NUMERO_CANDIDATO  <int> 12, 13, 15, 16, 17, 18, 19, 27, 30, 45, 50, 51, 54,…
## $ CODIGO_MACRO      <int> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, …
## $ NOME_MACRO        <chr> "Sudeste", "Sudeste", "Sudeste", "Sudeste", "Sudest…
## $ UF                <chr> "RJ", "RJ", "RJ", "RJ", "RJ", "RJ", "RJ", "RJ", "RJ…
## $ NOME_UF           <chr> "Rio de Janeiro", "Rio de Janeiro", "Rio de Janeiro…
## $ CODIGO_MESO       <int> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, …
## $ NOME_MESO         <chr> "Sul Fluminense", "Sul Fluminense", "Sul Fluminense…
## $ CODIGO_MICRO      <int> 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,…
## $ NOME_MICRO        <chr> "Baía da Ilha Grande", "Baía da Ilha Grande", "Baía…
## $ COD_MUN_TSE       <int> 58017, 58017, 58017, 58017, 58017, 58017, 58017, 58…
## $ COD_MUN_IBGE      <int> 3300100, 3300100, 3300100, 3300100, 3300100, 330010…
## $ NOME_MUNICIPIO    <chr> "Angra dos Reis", "Angra dos Reis", "Angra dos Reis…
## $ QTDE_VOTOS        <int> 8696, 13204, 565, 34, 59499, 662, 349, 32, 998, 190…

Introdução ao Dplyr.

O dplyr é um dos pacotes mais populares em R. Sua lógica é simples: suas funções fazem exatamente o que seus nomes descrevem (verb based language). Seu uso torna nosso código mais intuitivo de seguir, entender e ler. Veja alguns exemplos.

Estas são as funções mais úteis do dplyr:

  • select(): selecionar colunas.

  • filter(): filtrar o banco de dados por linhas.

  • mutate(): criar novas variáveis e alterar existentes.

  • arrange(): ordenar o banco de dados.

  • group_by(): agrupar e fazer análiser nos subgrupos.

  • summarize(): sumariza os dados por subgroups.

Algumas outras funções menos utilizadas:

  • count(): contar número de observações por subgrupos.

  • distinct(): eliminar repetições.

  • n(): conta quantas observações há em dados agrupados.

  • sample_n(): Selecion n amostras do seu banco de dadosl

  • glimpse(): Fornece um sumário dos seus dados.

  • top_n(): Seleciona por linhas de acordo com o rank das variáveis.

  • slice(): filtra seu banco de dados por posições.

Todas essas funções seguem as mesmas características:

  • O input é sempre um banco de dados.

  • O banco de dados é sempre o primeiro argumento.

  • Os argumentos acessam colunas dos bancos de dados diretamente, sem aspas.

  • O output é sempre um novo banco de dados.

Select: Seleciona Colunas.

Uso Básico.

pres_rio %>% # Dados
  select(ANO_ELEICAO, SIGLA_UE, NOME_MUNICIPIO, COD_MUN_IBGE) # colunas
## # A tibble: 1,374 x 4
##    ANO_ELEICAO SIGLA_UE NOME_MUNICIPIO COD_MUN_IBGE
##          <int> <chr>    <chr>                 <int>
##  1        2018 BR       Angra dos Reis      3300100
##  2        2018 BR       Angra dos Reis      3300100
##  3        2018 BR       Angra dos Reis      3300100
##  4        2018 BR       Angra dos Reis      3300100
##  5        2018 BR       Angra dos Reis      3300100
##  6        2018 BR       Angra dos Reis      3300100
##  7        2018 BR       Angra dos Reis      3300100
##  8        2018 BR       Angra dos Reis      3300100
##  9        2018 BR       Angra dos Reis      3300100
## 10        2018 BR       Angra dos Reis      3300100
## # … with 1,364 more rows

Reordenando Colunas

pres_rio %>% # Dados
  # seleciona colunas
  select(QTDE_VOTOS, ANO_ELEICAO, SIGLA_UE, 
         NOME_MUNICIPIO, COD_MUN_IBGE) # colunas
## # A tibble: 1,374 x 5
##    QTDE_VOTOS ANO_ELEICAO SIGLA_UE NOME_MUNICIPIO COD_MUN_IBGE
##         <int>       <int> <chr>    <chr>                 <int>
##  1       8696        2018 BR       Angra dos Reis      3300100
##  2      13204        2018 BR       Angra dos Reis      3300100
##  3        565        2018 BR       Angra dos Reis      3300100
##  4         34        2018 BR       Angra dos Reis      3300100
##  5      59499        2018 BR       Angra dos Reis      3300100
##  6        662        2018 BR       Angra dos Reis      3300100
##  7        349        2018 BR       Angra dos Reis      3300100
##  8         32        2018 BR       Angra dos Reis      3300100
##  9        998        2018 BR       Angra dos Reis      3300100
## 10       1909        2018 BR       Angra dos Reis      3300100
## # … with 1,364 more rows

Renomeando Colunas

pres_rio %>% 
  # seleciona colunas com novos nomes. 
  select(votos=QTDE_VOTOS, 
         ano=ANO_ELEICAO, 
         pais=SIGLA_UE, 
         mun=NOME_MUNICIPIO, 
         cod=COD_MUN_IBGE) # colunas
## # A tibble: 1,374 x 5
##    votos   ano pais  mun                cod
##    <int> <int> <chr> <chr>            <int>
##  1  8696  2018 BR    Angra dos Reis 3300100
##  2 13204  2018 BR    Angra dos Reis 3300100
##  3   565  2018 BR    Angra dos Reis 3300100
##  4    34  2018 BR    Angra dos Reis 3300100
##  5 59499  2018 BR    Angra dos Reis 3300100
##  6   662  2018 BR    Angra dos Reis 3300100
##  7   349  2018 BR    Angra dos Reis 3300100
##  8    32  2018 BR    Angra dos Reis 3300100
##  9   998  2018 BR    Angra dos Reis 3300100
## 10  1909  2018 BR    Angra dos Reis 3300100
## # … with 1,364 more rows

Salvando Novo Banco.

rio_reduzido <- pres_rio %>% # Dados
                  # seleciona colunas com novos nomes. 
                  select(votos=QTDE_VOTOS, 
                         ano=ANO_ELEICAO, 
                         pais=SIGLA_UE, 
                         mun=NOME_MUNICIPIO, 
                         cod=COD_MUN_IBGE) # colunas

Outros Atalhos para Uso do Select.

  • contains() - Extrai colunas que contêm determinado texto.

  • starts_with() - Extrai colunas que inicia com determinado texto.

  • ends_with() - Extrai colunas que termina com determinado texto.

  • everything() - Extrai todas as colunas restantes.

Exemplos

pres_rio %>%
  # seleciona colunas onde NOME aparece
  select(contains("NOME"))
## # A tibble: 1,374 x 5
##    NOME_MACRO NOME_UF        NOME_MESO      NOME_MICRO          NOME_MUNICIPIO
##    <chr>      <chr>          <chr>          <chr>               <chr>         
##  1 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
##  2 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
##  3 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
##  4 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
##  5 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
##  6 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
##  7 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
##  8 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
##  9 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 10 Sudeste    Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## # … with 1,364 more rows
pres_rio %>%
  # seleciona colunas que terminam com UF e 
  # todas as outras colunas restantes
  select(ends_with("UF"), everything())
## # A tibble: 1,374 x 19
##    UF    NOME_UF ANO_ELEICAO SIGLA_UE NUM_TURNO DESCRICAO_ELEIC… CODIGO_CARGO
##    <chr> <chr>         <int> <chr>        <int> <chr>                   <int>
##  1 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
##  2 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
##  3 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
##  4 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
##  5 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
##  6 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
##  7 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
##  8 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
##  9 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
## 10 RJ    Rio de…        2018 BR               1 ELEIÇÃO GERAL F…            1
## # … with 1,364 more rows, and 12 more variables: DESCRICAO_CARGO <chr>,
## #   NUMERO_CANDIDATO <int>, CODIGO_MACRO <int>, NOME_MACRO <chr>,
## #   CODIGO_MESO <int>, NOME_MESO <chr>, CODIGO_MICRO <int>, NOME_MICRO <chr>,
## #   COD_MUN_TSE <int>, COD_MUN_IBGE <int>, NOME_MUNICIPIO <chr>,
## #   QTDE_VOTOS <int>

Filter: Filtra Linhas por Condições Lógicas.

Uso Básico.

  filter(data, coluna=="a")
pres_rio %>%
  # filtra casos ondem partido igual a 17.
  filter(NUMERO_CANDIDATO==17) %>%
  # seleciona
  select(DESCRICAO_CARGO, NUMERO_CANDIDATO, QTDE_VOTOS, NOME_MUNICIPIO)
## # A tibble: 184 x 4
##    DESCRICAO_CARGO NUMERO_CANDIDATO QTDE_VOTOS NOME_MUNICIPIO    
##    <chr>                      <int>      <int> <chr>             
##  1 PRESIDENTE                    17      59499 Angra dos Reis    
##  2 PRESIDENTE                    17       4366 Aperibé           
##  3 PRESIDENTE                    17      44108 Araruama          
##  4 PRESIDENTE                    17       3816 Areal             
##  5 PRESIDENTE                    17      13028 Armação dos Búzios
##  6 PRESIDENTE                    17      13342 Arraial do Cabo   
##  7 PRESIDENTE                    17      27178 Barra do Piraí    
##  8 PRESIDENTE                    17      55972 Barra Mansa       
##  9 PRESIDENTE                    17     138676 Belford Roxo      
## 10 PRESIDENTE                    17       8077 Bom Jardim        
## # … with 174 more rows

Multiplas Condições

pres_rio %>%
  # filtra usando or
  filter(NUMERO_CANDIDATO==17 | NUMERO_CANDIDATO==13, # or
  #filtra usando and
         NOME_MUNICIPIO=="Rio de Janeiro") %>% # and
  #selecion
  select(DESCRICAO_CARGO, NUMERO_CANDIDATO, QTDE_VOTOS, NOME_MUNICIPIO)
## # A tibble: 4 x 4
##   DESCRICAO_CARGO NUMERO_CANDIDATO QTDE_VOTOS NOME_MUNICIPIO
##   <chr>                      <int>      <int> <chr>         
## 1 PRESIDENTE                    13     398033 Rio de Janeiro
## 2 PRESIDENTE                    17    1930657 Rio de Janeiro
## 3 PRESIDENTE                    13    1105393 Rio de Janeiro
## 4 PRESIDENTE                    17    2179896 Rio de Janeiro

Arrange: Ordena Linhas por Colunas.


Arrange: Uso Básico.

arrange(data, coluna)
pres_rio %>%
  # filtra pelas linhas
  filter(NUMERO_CANDIDATO==13) %>% 
  # seleciona
  select(DESCRICAO_CARGO, NUMERO_CANDIDATO,
         QTDE_VOTOS, NOME_MUNICIPIO) %>%
  # ordena de forma crescente
  arrange(QTDE_VOTOS)
## # A tibble: 184 x 4
##    DESCRICAO_CARGO NUMERO_CANDIDATO QTDE_VOTOS NOME_MUNICIPIO               
##    <chr>                      <int>      <int> <chr>                        
##  1 PRESIDENTE                    13        830 São José do Vale do Rio Preto
##  2 PRESIDENTE                    13       1111 Areal                        
##  3 PRESIDENTE                    13       1115 Santa Maria Madalena         
##  4 PRESIDENTE                    13       1129 Aperibé                      
##  5 PRESIDENTE                    13       1152 São José de Ubá              
##  6 PRESIDENTE                    13       1224 Macuco                       
##  7 PRESIDENTE                    13       1241 Varre-Sai                    
##  8 PRESIDENTE                    13       1342 Italva                       
##  9 PRESIDENTE                    13       1448 São Sebastião do Alto        
## 10 PRESIDENTE                    13       1455 Duas Barras                  
## # … with 174 more rows

Arrange: Decrescente

pres_rio %>%
  # filtra pelas linhas
  filter(NUMERO_CANDIDATO==13) %>% 
  # seleciona variáveis
  select(DESCRICAO_CARGO, NUMERO_CANDIDATO, 
         QTDE_VOTOS, NOME_MUNICIPIO) %>%
  # ordena em valores descrecentes
  arrange(desc(QTDE_VOTOS))
## # A tibble: 184 x 4
##    DESCRICAO_CARGO NUMERO_CANDIDATO QTDE_VOTOS NOME_MUNICIPIO       
##    <chr>                      <int>      <int> <chr>                
##  1 PRESIDENTE                    13    1105393 Rio de Janeiro       
##  2 PRESIDENTE                    13     398033 Rio de Janeiro       
##  3 PRESIDENTE                    13     149075 São Gonçalo          
##  4 PRESIDENTE                    13     136240 Duque de Caxias      
##  5 PRESIDENTE                    13     110820 Nova Iguaçu          
##  6 PRESIDENTE                    13     105606 Niterói              
##  7 PRESIDENTE                    13      80858 São Gonçalo          
##  8 PRESIDENTE                    13      79838 Campos dos Goytacazes
##  9 PRESIDENTE                    13      77504 Duque de Caxias      
## 10 PRESIDENTE                    13      70499 São João de Meriti   
## # … with 174 more rows

Mutate: Adiciona uma nova coluna.

Uso Básico:

mutate(data, nome_nova_coluna=valores_nova_coluna)
pres_rio %>%
  # cria variável com estado e cidade
  mutate(estado_cidade=paste(NOME_MUNICIPIO, "-", NOME_UF)) %>%
  #seleciona para visualizar
  select(NOME_MUNICIPIO, NOME_UF, estado_cidade)
## # A tibble: 1,374 x 3
##    NOME_MUNICIPIO NOME_UF        estado_cidade                  
##    <chr>          <chr>          <chr>                          
##  1 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
##  2 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
##  3 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
##  4 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
##  5 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
##  6 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
##  7 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
##  8 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
##  9 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 10 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## # … with 1,364 more rows

Condicionais

pres_rio %>%
  # cria variável usando condicionais
  mutate(estado_sigla=ifelse(NOME_UF=="Rio de Janeiro", "RJ", NA), 
  # concatena nova variável com cidade
         estado_cidade=paste(estado_sigla, "-", NOME_MUNICIPIO)) %>%
  #selectiona
  select(NOME_UF, NOME_MUNICIPIO, estado_sigla, everything())
## # A tibble: 1,374 x 21
##    NOME_UF NOME_MUNICIPIO estado_sigla ANO_ELEICAO SIGLA_UE NUM_TURNO
##    <chr>   <chr>          <chr>              <int> <chr>        <int>
##  1 Rio de… Angra dos Reis RJ                  2018 BR               1
##  2 Rio de… Angra dos Reis RJ                  2018 BR               1
##  3 Rio de… Angra dos Reis RJ                  2018 BR               1
##  4 Rio de… Angra dos Reis RJ                  2018 BR               1
##  5 Rio de… Angra dos Reis RJ                  2018 BR               1
##  6 Rio de… Angra dos Reis RJ                  2018 BR               1
##  7 Rio de… Angra dos Reis RJ                  2018 BR               1
##  8 Rio de… Angra dos Reis RJ                  2018 BR               1
##  9 Rio de… Angra dos Reis RJ                  2018 BR               1
## 10 Rio de… Angra dos Reis RJ                  2018 BR               1
## # … with 1,364 more rows, and 15 more variables: DESCRICAO_ELEICAO <chr>,
## #   CODIGO_CARGO <int>, DESCRICAO_CARGO <chr>, NUMERO_CANDIDATO <int>,
## #   CODIGO_MACRO <int>, NOME_MACRO <chr>, UF <chr>, CODIGO_MESO <int>,
## #   NOME_MESO <chr>, CODIGO_MICRO <int>, NOME_MICRO <chr>, COD_MUN_TSE <int>,
## #   COD_MUN_IBGE <int>, QTDE_VOTOS <int>, estado_cidade <chr>

Operações Matemáticas.

pres_rio %>%
  # log dos votos
  mutate(log_votos=log(QTDE_VOTOS)) %>%
  # seleciona
  select(QTDE_VOTOS, log_votos)
## # A tibble: 1,374 x 2
##    QTDE_VOTOS log_votos
##         <int>     <dbl>
##  1       8696      9.07
##  2      13204      9.49
##  3        565      6.34
##  4         34      3.53
##  5      59499     11.0 
##  6        662      6.50
##  7        349      5.86
##  8         32      3.47
##  9        998      6.91
## 10       1909      7.55
## # … with 1,364 more rows

Group_by + Summarize.

Uma tarefa muito comum quando manipulamos bancos de dados é calcular valores para determinados subgroups. Por exemplo:

  • Qual a votação total dos candidatos a presidência agregados ao nível do Estado do Rio de Janeiro ?

  • Qual o total de votos por município por candidato?

  • Em qual micro-região Jair Bolsonaro saiu com maior vantagem no primeiro turno?

Para responder esta perguntas, faremos uso da combinação entre as funções group_by e summarize.

Group_by

O primeiro passo é agrupar o banco de dados de acordo com a variável de nosso interesse.

pres_rio %>%
  # agrupando por candidato presidencial
  group_by(NUMERO_CANDIDATO) 
## # A tibble: 1,374 x 19
## # Groups:   NUMERO_CANDIDATO [13]
##    ANO_ELEICAO SIGLA_UE NUM_TURNO DESCRICAO_ELEIC… CODIGO_CARGO DESCRICAO_CARGO
##          <int> <chr>        <int> <chr>                   <int> <chr>          
##  1        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  2        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  3        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  4        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  5        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  6        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  7        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  8        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  9        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
## 10        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
## # … with 1,364 more rows, and 13 more variables: NUMERO_CANDIDATO <int>,
## #   CODIGO_MACRO <int>, NOME_MACRO <chr>, UF <chr>, NOME_UF <chr>,
## #   CODIGO_MESO <int>, NOME_MESO <chr>, CODIGO_MICRO <int>, NOME_MICRO <chr>,
## #   COD_MUN_TSE <int>, COD_MUN_IBGE <int>, NOME_MUNICIPIO <chr>,
## #   QTDE_VOTOS <int>

IMPORTANTE: 0 group_by somente agrupa seu banco. É como se criassêmos diversos mini-bancos de dados no background do R.

A partir disso, podemos usar summarize para calcular valores de nosso interesse neste subgrupos.

Summarize.

Uso básico:

summarize(dados_agrupados, nome_nova_variavel=valores_calculados)
pres_rio %>%
  # Somente primeiro turno 
  filter(NUM_TURNO==1) %>%
  # agrupando por candidato presidencial
  group_by(NUMERO_CANDIDATO) %>%
  # Somando os votos em todo o estado.
  summarise(voto_estado=sum(QTDE_VOTOS)) %>%
  # Ordena
  arrange(desc(voto_estado))
## # A tibble: 13 x 2
##    NUMERO_CANDIDATO voto_estado
##               <int>       <int>
##  1               17     5107735
##  2               12     1300292
##  3               13     1255425
##  4               51      211444
##  5               45      208325
##  6               30      139208
##  7               18      130794
##  8               15       77333
##  9               50       57846
## 10               19       41544
## 11               16        6005
## 12               27        4636
## 13               54        2806

Perceba: o summarize transforma múltiplas linhas em uma para cada subgrupo

Exemplos de operações com summarize

  • min(x) - minimo de x.
  • max(x) - máximo de x.
  • mean(x) - média de x.
  • median(x) - mediana de x.
  • quantile(x, p) - quantile de x.
  • sd(x) - desvio padrão de x.
  • var(x) - variancia de x.
  • n(x) - número de casos de x

E muitas outras!!

Mais Exemplos

Quem ganhou no Rio de Janeiro no Segundo Turno?

pres_rio %>%
  # Somente primeiro turno 
  filter(NUM_TURNO==2) %>%
  # agrupando por candidato presidencial
  group_by(NUMERO_CANDIDATO) %>%
  # Somando os votos em todo o estado.
  summarise(voto_estado=sum(QTDE_VOTOS)) %>%
  # Ordena
  arrange(desc(voto_estado))
## # A tibble: 2 x 2
##   NUMERO_CANDIDATO voto_estado
##              <int>       <int>
## 1               17     5669059
## 2               13     2673386

Total de Votos por Município

pres_rio %>%
  # Somente primeiro turno 
  filter(NUM_TURNO==1) %>%
  # agrupando por candidato presidencial
  group_by(NOME_MUNICIPIO) %>%
  # Somando os votos em todo o estado.
  summarise(voto_mun=sum(QTDE_VOTOS)) 
## # A tibble: 92 x 2
##    NOME_MUNICIPIO     voto_mun
##  * <chr>                 <int>
##  1 Angra dos Reis        88316
##  2 Aperibé                6680
##  3 Araruama              64481
##  4 Areal                  6921
##  5 Armação dos Búzios    19979
##  6 Arraial do Cabo       20133
##  7 Barra do Piraí        48942
##  8 Barra Mansa           96980
##  9 Belford Roxo         226785
## 10 Bom Jardim            14090
## # … with 82 more rows

Votos por Meso-Região

pres_rio %>%
  # Somente primeiro turno 
  filter(NUM_TURNO==1) %>%
  # agrupando por candidato presidencial
  group_by(NUMERO_CANDIDATO, NOME_MESO) %>%
  # soma de votos por município
  summarise(voto_media=mean(QTDE_VOTOS), 
            voto_min=min(QTDE_VOTOS), 
            voto_max=max(QTDE_VOTOS))
## # A tibble: 78 x 5
## # Groups:   NUMERO_CANDIDATO [13]
##    NUMERO_CANDIDATO NOME_MESO                       voto_media voto_min voto_max
##               <int> <chr>                                <dbl>    <int>    <int>
##  1               12 Baixadas                             4769.     1157    13478
##  2               12 Centro Fluminense                    2558       403    16254
##  3               12 Metropolitana do Rio de Janeiro     35187.      702   645674
##  4               12 Noroeste Fluminense                  1393.      296     4684
##  5               12 Norte Fluminense                     6909.      798    33042
##  6               12 Sul Fluminense                       5412.      812    23860
##  7               13 Baixadas                             4409.     1574    10310
##  8               13 Centro Fluminense                    2954.     1111    10664
##  9               13 Metropolitana do Rio de Janeiro     31261.      830   398033
## 10               13 Noroeste Fluminense                  2789.     1129     8209
## # … with 68 more rows

Outras funções úteis.

Count: Contar por grupos.

pres_rio %>%
  # Quantas entradas para cada número candidato?
  count(NUMERO_CANDIDATO)
## # A tibble: 13 x 2
##    NUMERO_CANDIDATO     n
##  *            <int> <int>
##  1               12    92
##  2               13   184
##  3               15    92
##  4               16    91
##  5               17   184
##  6               18    92
##  7               19    92
##  8               27    92
##  9               30    92
## 10               45    92
## 11               50    92
## 12               51    92
## 13               54    87

Slice: Selecionar por posição das linhas.

pres_rio %>%
  slice(1:10)
## # A tibble: 10 x 19
##    ANO_ELEICAO SIGLA_UE NUM_TURNO DESCRICAO_ELEIC… CODIGO_CARGO DESCRICAO_CARGO
##          <int> <chr>        <int> <chr>                   <int> <chr>          
##  1        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  2        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  3        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  4        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  5        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  6        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  7        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  8        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  9        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
## 10        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
## # … with 13 more variables: NUMERO_CANDIDATO <int>, CODIGO_MACRO <int>,
## #   NOME_MACRO <chr>, UF <chr>, NOME_UF <chr>, CODIGO_MESO <int>,
## #   NOME_MESO <chr>, CODIGO_MICRO <int>, NOME_MICRO <chr>, COD_MUN_TSE <int>,
## #   COD_MUN_IBGE <int>, NOME_MUNICIPIO <chr>, QTDE_VOTOS <int>

rowid_to_column() : criar id para linhas

pres_rio %>% 
  rowid_to_column() %>%
  select(1:5)
## # A tibble: 1,374 x 5
##    rowid ANO_ELEICAO SIGLA_UE NUM_TURNO DESCRICAO_ELEICAO         
##    <int>       <int> <chr>        <int> <chr>                     
##  1     1        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
##  2     2        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
##  3     3        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
##  4     4        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
##  5     5        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
##  6     6        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
##  7     7        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
##  8     8        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
##  9     9        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
## 10    10        2018 BR               1 ELEIÇÃO GERAL FEDERAL 2018
## # … with 1,364 more rows

Desafio

Mutate x Summarize.

Qual a diferença entre as funções mutate and summarize? Porque os dois exemplos abaixo geram resultados distintos?

pres_rio %>%
  # Somente primeiro turno 
  filter(NUM_TURNO==1) %>%
  # agrupando por candidato presidencial
  group_by(NUMERO_CANDIDATO) %>%
  # Nova variável somando os votos em todo o estado.
  mutate(voto_estado=sum(QTDE_VOTOS))
## # A tibble: 1,190 x 20
## # Groups:   NUMERO_CANDIDATO [13]
##    ANO_ELEICAO SIGLA_UE NUM_TURNO DESCRICAO_ELEIC… CODIGO_CARGO DESCRICAO_CARGO
##          <int> <chr>        <int> <chr>                   <int> <chr>          
##  1        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  2        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  3        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  4        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  5        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  6        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  7        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  8        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
##  9        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
## 10        2018 BR               1 ELEIÇÃO GERAL F…            1 PRESIDENTE     
## # … with 1,180 more rows, and 14 more variables: NUMERO_CANDIDATO <int>,
## #   CODIGO_MACRO <int>, NOME_MACRO <chr>, UF <chr>, NOME_UF <chr>,
## #   CODIGO_MESO <int>, NOME_MESO <chr>, CODIGO_MICRO <int>, NOME_MICRO <chr>,
## #   COD_MUN_TSE <int>, COD_MUN_IBGE <int>, NOME_MUNICIPIO <chr>,
## #   QTDE_VOTOS <int>, voto_estado <int>

Praticando:

Abra o banco de dados de candidatos a deputado federal no Rio de Janeiro.

dep_rio <- get_candidates(year=2018,
                          position="Federal Deputy") %>%
           as_tibble()

Responda:

  1. Qual partido elegeu mais deputados? (3 linhas)

Dica: data %>% filter(COD_SIT_TOT_TURNO==2 | COD_SIT_TOT_TURNO==3) filtra somente os eleitos.

  1. Qual candidato gastou mais recursos ? (2-3 linhas)

  2. Qual valor médio declarado de gastos de campanha de acordo com o gênero dos candidatos? (3 linhas)

Conectando Bancos de Dados com Dplyr.

Raramente, você encontrará um banco de dados onde todas as informações da sua pesquisa estão contidas e prontas para serem analisadas.

Na maioria dos casos, e por boas razões, bancos de dados possuem informações distintas e complementares, e os pesquisadores precisam conectá-los com vistas a construir o material necessário para suas análises.

Este tipo de dados conectados a partir de várias tabelas são chamados de dados relacionais. Dados eleitorais no Brasil providos pelo TSE, por exemplo, vem com pedaços distintos de informação, que podem, a depender dos objetivos de sua análise, ser conectados. De forma mais concreta, estes são alguns exemplos de bancos disponíveis no TSE:

  • Candidatos: arrecadação, nome, profissão, etc.

  • Votação: dados de votação por município, zonal, seção eleitoral.

  • Eleitorado: perfil dos eleitores registrados no nível da zona eleitoral.

Chaves (keys)

Ainda nos casos dos bancos de dados do TSE, por exemplo, usando o número do candidato e a unidade eleitoral é possível conectar os bancos de candidatos e votação, ou usando o número da zona eleitoral por município, conectar votação e eleitorado. A partir dessa conexão, nossas análises ficam mais completes e interessantes.

Estas variáveis capazes de conectar bancos de dados são chamadas chaves. Estas chaves devem ser:

  • Completas. Nunca tenha missing values nas suas chaves.

  • Únicas: cada observação deve possuir uma chave distinta. Evite sempre duplicações.

Joins

Inspirado na linguaguem SQL, o dplyr possui um conjunto de funções com foco em conectar bancos de dados distintos.

Vamos criar dois bancos bem simples para entendermos como estes joins funcionam.

data1 <- tibble(nome=c("A", "B", "C"), 
                value=c(10, 20, 30)) 
data2 <- tibble(nome=c("A", "D", "C"), 
                value2=c(10, 50, 30))

left_join()

left_join(data1, data2)
## # A tibble: 3 x 3
##   nome  value value2
##   <chr> <dbl>  <dbl>
## 1 A        10     10
## 2 B        20     NA
## 3 C        30     30

inner_join()

inner_join(data1, data2)
## # A tibble: 2 x 3
##   nome  value value2
##   <chr> <dbl>  <dbl>
## 1 A        10     10
## 2 C        30     30

full_join()

full_join(data1, data2)
## # A tibble: 4 x 3
##   nome  value value2
##   <chr> <dbl>  <dbl>
## 1 A        10     10
## 2 B        20     NA
## 3 C        30     30
## 4 D        NA     50

Chaves Distintas?

Em inúmeros casos, os bancos que precisamos conectar terá nomes diferentes. Este problema é fácil de resolver. É preciso adicionar o argumento dos nomes, e ajudar as funções joins a fazerem seu serviço.

data3 <- data2 %>%
          # alterando o nome
          select(chave=nome, everything())

# Join

left_join(data1, data3, 
          by=c("nome"="chave")) # adicione argumento by.
## # A tibble: 3 x 3
##   nome  value value2
##   <chr> <dbl>  <dbl>
## 1 A        10     10
## 2 B        20     NA
## 3 C        30     30

Múltiplas Chaves

A lógica para múltiplas chaves é semelhante: precisamos específicar seus nomes na função by.

data3 <- data2 %>%
          # alterando o nome
          select(nome, value=value2)

left_join(data1, data3, by=c("nome", "value"))
## # A tibble: 3 x 2
##   nome  value
##   <chr> <dbl>
## 1 A        10
## 2 B        20
## 3 C        30

Desafio

Abra os bancos de dados de candidatos e votos do TSE. Faça um join entre eles, e salve o banco de dados.

  • Quantas linhas este novo banco de dados possuí?

  • Explique o número de linhas.

# Banco Candidatos
candidatos <- get_candidates(year=2018, position="President") %>% 
                as_tibble()

# Banco Votos
votos <- get_votes(year = 2018, position="President", state="RJ") %>%
            as_tibble()
# Join? 

Concatenando Bancos de Dados

Além de juntar bancos de dados usando chaves, podemos concatecar bancos verticalmente (pelas linhas) ou horizontalmente (pelas colunas).

bind_rows: por linhas

bind_rows(data1, data2)
## # A tibble: 6 x 3
##   nome  value value2
##   <chr> <dbl>  <dbl>
## 1 A        10     NA
## 2 B        20     NA
## 3 C        30     NA
## 4 A        NA     10
## 5 D        NA     50
## 6 C        NA     30

Note: ao conectar por linha, as colunas precisam ter os mesmos nomes. Caso não, você adicionará uma nova variável ao resultado final.

bind_cols: por colunas

bind_cols(data1, data2)
## # A tibble: 3 x 4
##   nome...1 value nome...3 value2
##   <chr>    <dbl> <chr>     <dbl>
## 1 A           10 A            10
## 2 B           20 D            50
## 3 C           30 C            30

Note: ao conectar por coluna, as linhas precisam ter tamanho igual.

Exercícios!

No site do curso, estão disponíveis os exercícios da semana. Vamos praticar!