3  Dia 2 - Importação e transformação

Ministrante

3.1 Importação de dados

3.1.1 Dados utilizados: Eleições de 2024

Os dados que utilizaremos nesse curso são provenientes de uma base de dados do Tribunal Superior Eleitoral (TSE) do Brasil, que contém informações sobre candidatos para as eleições de 2024. A base de dados original foi baixada do portal de dados abertos do TSE: Candidatos - 2024. Para facilitar o download dos dados durante a atividade, filtramos a tabela para dados do município de São Paulo, apenas candidatos(as) para o cargo de Vereador, e unimos com os dados de resultados (soma de votos válidos).

Junto aos dados, o TSE disponibiliza também um arquivo chamado leiame.pdf, com informações importantes sobre os dados, significado dos nomes das colunas, entre outros. É importante ler estes arquivos, quando disponibilizados.

Vamos utilizar o pacote tidyverse para importar os dados, então é importante garantir que ele esteja carregado:

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.2     ✔ tibble    3.3.0
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.0.4     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

O arquivo que queremos importar é esse aqui: candidatos_vereador_com_votos.csv. Ele é um arquivo .csv (CSV = comma separated values, ou valores separados por vírgula), porém o separador utilizado é o ;.

Para importar esse arquivo, podemos utilizar a função read_csv2() (a função read_csv() é utilizada para importar tabelas com valores separados por vírgula):

dados <- read_csv2("https://raw.githubusercontent.com/beatrizmilz/2025-07-fbcp/refs/heads/main/intro-r/dados/candidatos_vereador_com_votos.csv")

Caso o arquivo esteja salvo no projeto, também podemos importar os dados utilizando o caminho relativo do arquivo:

dados <- read_csv2("dados/candidatos_vereador_com_votos.csv")
ℹ Using "','" as decimal and "'.'" as grouping mark. Use `read_delim()` for more control.
Rows: 1016 Columns: 51
── Column specification ────────────────────────────────────────────────────────
Delimiter: ";"
chr  (31): DT_GERACAO, NM_TIPO_ELEICAO, DS_ELEICAO, DT_ELEICAO, TP_ABRANGENC...
dbl  (19): ANO_ELEICAO, CD_TIPO_ELEICAO, NR_TURNO, CD_ELEICAO, SG_UE, CD_CAR...
time  (1): HH_GERACAO

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

A função View() pode ser utilizada para visualizar os dados em uma tabela interativa:

View(dados)
Nota

As funções de importação costumam ser específicas para o tipo de arquivo que você está tentando importar. Abaixo estão algumas das funções mais comuns do pacote readr e outros pacotes para importar diferentes tipos de arquivos:

Função Pacote Extensão do arquivo Descrição
read_csv() readr .csv Separador: ,
read_csv2() readr .csv Separador: ;
read_delim() readr .txt, .tsv,.csv, etc. Permite especificar o separador
read_rds() readr .rds Importa arquivos RDS (R data files)
read_excel() readxl .xlsx, .xls Importa arquivos do Excel
read_sheet() googlesheets4 - Importa planilhas do Google Sheets
read_sf() sf .geojson, .shp, etc. Importa dados espaciais (geográficos)
read_parquet() arrow .parquet Importa arquivos Parquet (formato de armazenamento colunar)

3.1.2 Conhecendo a base de dados

Para conhecer melhor a base de dados, podemos utilizar algumas funções para explorar as colunas e os tipos de dados.

A função nrow() nos mostra o número de linhas da base de dados, e a função ncol() nos mostra o número de colunas:

nrow(dados)
[1] 1016
ncol(dados)
[1] 51

A função colnames() nos mostra os nomes das colunas:

colnames(dados)
 [1] "DT_GERACAO"                     "HH_GERACAO"                    
 [3] "ANO_ELEICAO"                    "CD_TIPO_ELEICAO"               
 [5] "NM_TIPO_ELEICAO"                "NR_TURNO"                      
 [7] "CD_ELEICAO"                     "DS_ELEICAO"                    
 [9] "DT_ELEICAO"                     "TP_ABRANGENCIA"                
[11] "SG_UF"                          "SG_UE"                         
[13] "NM_UE"                          "CD_CARGO"                      
[15] "DS_CARGO"                       "SQ_CANDIDATO"                  
[17] "NR_CANDIDATO"                   "NM_CANDIDATO"                  
[19] "NM_URNA_CANDIDATO"              "NM_SOCIAL_CANDIDATO"           
[21] "NR_CPF_CANDIDATO"               "DS_EMAIL"                      
[23] "CD_SITUACAO_CANDIDATURA"        "DS_SITUACAO_CANDIDATURA"       
[25] "TP_AGREMIACAO"                  "NR_PARTIDO"                    
[27] "SG_PARTIDO"                     "NM_PARTIDO"                    
[29] "NR_FEDERACAO"                   "NM_FEDERACAO"                  
[31] "SG_FEDERACAO"                   "DS_COMPOSICAO_FEDERACAO"       
[33] "SQ_COLIGACAO"                   "NM_COLIGACAO"                  
[35] "DS_COMPOSICAO_COLIGACAO"        "SG_UF_NASCIMENTO"              
[37] "DT_NASCIMENTO"                  "NR_TITULO_ELEITORAL_CANDIDATO" 
[39] "CD_GENERO"                      "DS_GENERO"                     
[41] "CD_GRAU_INSTRUCAO"              "DS_GRAU_INSTRUCAO"             
[43] "CD_ESTADO_CIVIL"                "DS_ESTADO_CIVIL"               
[45] "CD_COR_RACA"                    "DS_COR_RACA"                   
[47] "CD_OCUPACAO"                    "DS_OCUPACAO"                   
[49] "CD_SIT_TOT_TURNO"               "DS_SIT_TOT_TURNO"              
[51] "SOMA_QT_VOTOS_NOMINAIS_VALIDOS"

A função head() nos mostra as primeiras linhas da base de dados, e a função tail() nos mostra as últimas linhas:

head(dados)
# A tibble: 6 × 51
  DT_GERACAO HH_GERACAO ANO_ELEICAO CD_TIPO_ELEICAO NM_TIPO_ELEICAO   NR_TURNO
  <chr>      <time>           <dbl>           <dbl> <chr>                <dbl>
1 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
2 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
3 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
4 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
5 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
6 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
# ℹ 45 more variables: CD_ELEICAO <dbl>, DS_ELEICAO <chr>, DT_ELEICAO <chr>,
#   TP_ABRANGENCIA <chr>, SG_UF <chr>, SG_UE <dbl>, NM_UE <chr>,
#   CD_CARGO <dbl>, DS_CARGO <chr>, SQ_CANDIDATO <dbl>, NR_CANDIDATO <dbl>,
#   NM_CANDIDATO <chr>, NM_URNA_CANDIDATO <chr>, NM_SOCIAL_CANDIDATO <chr>,
#   NR_CPF_CANDIDATO <dbl>, DS_EMAIL <chr>, CD_SITUACAO_CANDIDATURA <dbl>,
#   DS_SITUACAO_CANDIDATURA <chr>, TP_AGREMIACAO <chr>, NR_PARTIDO <dbl>,
#   SG_PARTIDO <chr>, NM_PARTIDO <chr>, NR_FEDERACAO <dbl>, …
tail(dados)
# A tibble: 6 × 51
  DT_GERACAO HH_GERACAO ANO_ELEICAO CD_TIPO_ELEICAO NM_TIPO_ELEICAO   NR_TURNO
  <chr>      <time>           <dbl>           <dbl> <chr>                <dbl>
1 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
2 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
3 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
4 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
5 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
6 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
# ℹ 45 more variables: CD_ELEICAO <dbl>, DS_ELEICAO <chr>, DT_ELEICAO <chr>,
#   TP_ABRANGENCIA <chr>, SG_UF <chr>, SG_UE <dbl>, NM_UE <chr>,
#   CD_CARGO <dbl>, DS_CARGO <chr>, SQ_CANDIDATO <dbl>, NR_CANDIDATO <dbl>,
#   NM_CANDIDATO <chr>, NM_URNA_CANDIDATO <chr>, NM_SOCIAL_CANDIDATO <chr>,
#   NR_CPF_CANDIDATO <dbl>, DS_EMAIL <chr>, CD_SITUACAO_CANDIDATURA <dbl>,
#   DS_SITUACAO_CANDIDATURA <chr>, TP_AGREMIACAO <chr>, NR_PARTIDO <dbl>,
#   SG_PARTIDO <chr>, NM_PARTIDO <chr>, NR_FEDERACAO <dbl>, …

A função glimpse() apresenta várias informações relevantes: número de linhas, número de colunas, nome das colunas, valores de algumas observações, etc.

glimpse(dados)
Rows: 1,016
Columns: 51
$ DT_GERACAO                     <chr> "18/07/2025", "18/07/2025", "18/07/2025…
$ HH_GERACAO                     <time> 12:30:11, 12:30:11, 12:30:11, 12:30:11…
$ ANO_ELEICAO                    <dbl> 2024, 2024, 2024, 2024, 2024, 2024, 202…
$ CD_TIPO_ELEICAO                <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, …
$ NM_TIPO_ELEICAO                <chr> "ELEIÇÃO ORDINÁRIA", "ELEIÇÃO ORDINÁRIA…
$ NR_TURNO                       <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ CD_ELEICAO                     <dbl> 619, 619, 619, 619, 619, 619, 619, 619,…
$ DS_ELEICAO                     <chr> "Eleições Municipais 2024", "Eleições M…
$ DT_ELEICAO                     <chr> "06/10/2024", "06/10/2024", "06/10/2024…
$ TP_ABRANGENCIA                 <chr> "MUNICIPAL", "MUNICIPAL", "MUNICIPAL", …
$ SG_UF                          <chr> "SP", "SP", "SP", "SP", "SP", "SP", "SP…
$ SG_UE                          <dbl> 71072, 71072, 71072, 71072, 71072, 7107…
$ NM_UE                          <chr> "SÃO PAULO", "SÃO PAULO", "SÃO PAULO", …
$ CD_CARGO                       <dbl> 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,…
$ DS_CARGO                       <chr> "VEREADOR", "VEREADOR", "VEREADOR", "VE…
$ SQ_CANDIDATO                   <dbl> 250002371355, 250002371356, 25000237135…
$ NR_CANDIDATO                   <dbl> 36541, 36222, 36364, 36333, 77042, 7773…
$ NM_CANDIDATO                   <chr> "GENTIL ALVES DOS SANTOS NETO", "JOSÉ S…
$ NM_URNA_CANDIDATO              <chr> "GENTIL VIGILANTE", "JOSÉ LIMA DO TRANS…
$ NM_SOCIAL_CANDIDATO            <chr> "#NULO", "#NULO", "#NULO", "#NULO", "#N…
$ NR_CPF_CANDIDATO               <dbl> -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,…
$ DS_EMAIL                       <chr> "NÃO DIVULGÁVEL", "NÃO DIVULGÁVEL", "NÃ…
$ CD_SITUACAO_CANDIDATURA        <dbl> -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,…
$ DS_SITUACAO_CANDIDATURA        <chr> "#NE", "#NE", "#NE", "#NE", "#NE", "#NE…
$ TP_AGREMIACAO                  <chr> "PARTIDO ISOLADO", "PARTIDO ISOLADO", "…
$ NR_PARTIDO                     <dbl> 36, 36, 36, 36, 77, 77, 77, 77, 77, 77,…
$ SG_PARTIDO                     <chr> "AGIR", "AGIR", "AGIR", "AGIR", "SOLIDA…
$ NM_PARTIDO                     <chr> "AGIR", "AGIR", "AGIR", "AGIR", "SOLIDA…
$ NR_FEDERACAO                   <dbl> -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,…
$ NM_FEDERACAO                   <chr> "#NULO", "#NULO", "#NULO", "#NULO", "#N…
$ SG_FEDERACAO                   <chr> "#NULO", "#NULO", "#NULO", "#NULO", "#N…
$ DS_COMPOSICAO_FEDERACAO        <chr> "#NULO", "#NULO", "#NULO", "#NULO", "#N…
$ SQ_COLIGACAO                   <dbl> 250001762261, 250001762261, 25000176226…
$ NM_COLIGACAO                   <chr> "PARTIDO ISOLADO", "PARTIDO ISOLADO", "…
$ DS_COMPOSICAO_COLIGACAO        <chr> "AGIR", "AGIR", "AGIR", "AGIR", "SOLIDA…
$ SG_UF_NASCIMENTO               <chr> "SP", "BA", "SP", "SP", "SP", "MG", "SP…
$ DT_NASCIMENTO                  <chr> "23/05/1968", "26/11/1960", "23/08/1958…
$ NR_TITULO_ELEITORAL_CANDIDATO  <chr> "039430770141", "093136380124", "138148…
$ CD_GENERO                      <dbl> 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 4, 4, 4, …
$ DS_GENERO                      <chr> "MASCULINO", "MASCULINO", "MASCULINO", …
$ CD_GRAU_INSTRUCAO              <dbl> 8, 6, 8, 6, 8, 8, 8, 8, 8, 5, 5, 6, 8, …
$ DS_GRAU_INSTRUCAO              <chr> "SUPERIOR COMPLETO", "ENSINO MÉDIO COMP…
$ CD_ESTADO_CIVIL                <dbl> 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 9, 3, …
$ DS_ESTADO_CIVIL                <chr> "CASADO(A)", "CASADO(A)", "CASADO(A)", …
$ CD_COR_RACA                    <chr> "01", "01", "02", "01", "02", "03", "01…
$ DS_COR_RACA                    <chr> "BRANCA", "BRANCA", "PRETA", "BRANCA", …
$ CD_OCUPACAO                    <dbl> 254, 531, 923, 923, 999, 923, 157, 169,…
$ DS_OCUPACAO                    <chr> "VIGILANTE", "MOTORISTA DE VEÍCULOS DE …
$ CD_SIT_TOT_TURNO               <dbl> 4, -1, -1, -1, 4, 4, 4, 4, 4, 4, 4, 4, …
$ DS_SIT_TOT_TURNO               <chr> "NÃO ELEITO", "#NULO", "#NULO", "#NULO"…
$ SOMA_QT_VOTOS_NOMINAIS_VALIDOS <dbl> NA, NA, NA, NA, 224, 985, 49, 843, 299,…

3.2 Transformação de dados

Vamos conhecer as funções mais importantes do pacote dplyr para transformação de dados (também conhecido como manipulação de dados - data wrangling).

3.3 Conhecendo o operador pipe (|>)

O operador pipe (|> ou %>%) permite encadear operações de forma mais legível e intuitiva.

Por exemplo, podemos utilizar o operador pipe para aplicar a função glimpse() diretamente nos dados:

dados |> 
  glimpse()

Com apenas uma função, não é tão óbvio o benefício do operador pipe. No entanto, quando começamos a encadear várias funções, ele se torna muito útil. Veremos exemplos disso ao longo desta aula!

3.4 Principais verbos do dplyr

O pacote dplyr é uma das ferramentas mais poderosas para manipulação de dados no R. Ele oferece uma série de funções que facilitam a transformação e análise de dados. Vamos conhecer algumas das principais funções do dplyr:

  • select(): seleciona colunas específicas de um data frame.

  • arrange(): ordena as linhas de um data frame com base em uma ou mais colunas.

  • filter(): filtra linhas com base em condições específicas.

  • mutate(): adiciona ou modifica colunas.

  • summarise(): resume os dados, calculando estatísticas agregadas.

  • group_by(): agrupa os dados com base em uma ou mais colunas, permitindo aplicar funções de resumo a cada grupo.

Ao apresentar essas funções, não vamos abordar todos os casos de uso, mas sim o básico de cada uma delas. Você pode consultar os materiais extras para aprender mais sobre cada função e suas possibilidades.

3.5 Selecionando colunas com select()

A função select() é utilizada para selecionar colunas específicas de um data frame.

Por exemplo, podemos selecionar apenas um conjunto de colunas de interesse:

dados_selecionados <- dados |>
  select(NM_CANDIDATO, SG_PARTIDO, DS_SIT_TOT_TURNO, SOMA_QT_VOTOS_NOMINAIS_VALIDOS)

dados_selecionados
# A tibble: 1,016 × 4
   NM_CANDIDATO               SG_PARTIDO DS_SIT_TOT_TURNO SOMA_QT_VOTOS_NOMINA…¹
   <chr>                      <chr>      <chr>                             <dbl>
 1 GENTIL ALVES DOS SANTOS N… AGIR       NÃO ELEITO                           NA
 2 JOSÉ SILVA LIMA            AGIR       #NULO                                NA
 3 JOSÉ GILMAR ARAÚJO DOS SA… AGIR       #NULO                                NA
 4 OSVALDO BARROS FRANCO      AGIR       #NULO                                NA
 5 MÁRCIO PEDRAZA AGUILERA    SOLIDARIE… NÃO ELEITO                          224
 6 NEZINHO GONÇALVES NUNES    SOLIDARIE… NÃO ELEITO                          985
 7 ANGELA BARBOSA DOS SANTOS  SOLIDARIE… NÃO ELEITO                           49
 8 MARCO BATISTA DE OLIVEIRA  SOLIDARIE… NÃO ELEITO                          843
 9 RUBENS MASSASHI ITO        SOLIDARIE… NÃO ELEITO                          299
10 DEIVIDE ALEXANDRE DOS SAN… SOLIDARIE… NÃO ELEITO                          223
# ℹ 1,006 more rows
# ℹ abbreviated name: ¹​SOMA_QT_VOTOS_NOMINAIS_VALIDOS

Podemos também indicar quais colunas queremos excluir, utilizando o operador - antes do nome da coluna. Por exemplo, para excluir as colunas DT_GERACAO e HH_GERACAO, podemos:

dados |>
  select(-DT_GERACAO, -HH_GERACAO)
# A tibble: 1,016 × 49
   ANO_ELEICAO CD_TIPO_ELEICAO NM_TIPO_ELEICAO   NR_TURNO CD_ELEICAO DS_ELEICAO 
         <dbl>           <dbl> <chr>                <dbl>      <dbl> <chr>      
 1        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
 2        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
 3        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
 4        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
 5        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
 6        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
 7        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
 8        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
 9        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
10        2024               2 ELEIÇÃO ORDINÁRIA        1        619 Eleições M…
# ℹ 1,006 more rows
# ℹ 43 more variables: DT_ELEICAO <chr>, TP_ABRANGENCIA <chr>, SG_UF <chr>,
#   SG_UE <dbl>, NM_UE <chr>, CD_CARGO <dbl>, DS_CARGO <chr>,
#   SQ_CANDIDATO <dbl>, NR_CANDIDATO <dbl>, NM_CANDIDATO <chr>,
#   NM_URNA_CANDIDATO <chr>, NM_SOCIAL_CANDIDATO <chr>, NR_CPF_CANDIDATO <dbl>,
#   DS_EMAIL <chr>, CD_SITUACAO_CANDIDATURA <dbl>,
#   DS_SITUACAO_CANDIDATURA <chr>, TP_AGREMIACAO <chr>, NR_PARTIDO <dbl>, …

3.6 Ordenando dados com arrange()

A função arrange() é utilizada para ordenar as linhas de um data frame com base em uma ou mais colunas.

Podemos ordenar os dados de dados_selecionados pela coluna SOMA_QT_VOTOS_NOMINAIS_VALIDOS, utilizando a função arrange(). Mas atenção: por padrão, a função arrange() ordena os dados em ordem crescente.

dados_selecionados |>
  arrange(SOMA_QT_VOTOS_NOMINAIS_VALIDOS)
# A tibble: 1,016 × 4
   NM_CANDIDATO               SG_PARTIDO DS_SIT_TOT_TURNO SOMA_QT_VOTOS_NOMINA…¹
   <chr>                      <chr>      <chr>                             <dbl>
 1 CARLOS ANDRE FURTADO       SOLIDARIE… NÃO ELEITO                            0
 2 PAULO CAINE DOS SANTOS SI… MOBILIZA   NÃO ELEITO                            0
 3 VAGNER COELHO DO NASCIMEN… DC         NÃO ELEITO                            0
 4 GERSON DA CUNHA            SOLIDARIE… NÃO ELEITO                            0
 5 VERA LÚCIA SANTOS DE FRAN… AGIR       NÃO ELEITO                            0
 6 APARECIDO BESERRA MONTEIRO PSDB       NÃO ELEITO                            0
 7 CESAR FERREIRA LONGARES    DC         NÃO ELEITO                            0
 8 DIEGO DOS REIS SILVA       REPUBLICA… NÃO ELEITO                            0
 9 GISELE DA SILVA            PSDB       NÃO ELEITO                            0
10 MARCO ANTONIO DA SILVA     MOBILIZA   NÃO ELEITO                            0
# ℹ 1,006 more rows
# ℹ abbreviated name: ¹​SOMA_QT_VOTOS_NOMINAIS_VALIDOS

Aparentemente, existem alguns candidatos que não receberam votos válidos.

Também podemos ordenar os dados em ordem decrescente, utilizando a função desc():

dados_selecionados |>
  arrange(desc(SOMA_QT_VOTOS_NOMINAIS_VALIDOS))
# A tibble: 1,016 × 4
   NM_CANDIDATO               SG_PARTIDO DS_SIT_TOT_TURNO SOMA_QT_VOTOS_NOMINA…¹
   <chr>                      <chr>      <chr>                             <dbl>
 1 LUCAS PAVANATO DE OLIVEIRA PL         ELEITO POR QP                    161386
 2 ANA CAROLINA CUNHA DE OLI… PODE       ELEITO POR QP                    129563
 3 MURILLO DE OLIVEIRA LIMA   PP         ELEITO POR QP                    113820
 4 ISRAEL NANTES SANTOS       PP         ELEITO POR QP                    112484
 5 AMANDA MARQUES PASCHOAL    PSOL       ELEITO POR QP                    108654
 6 RUBENS ALBERTO GATTI NUNES UNIÃO      ELEITO POR QP                    101549
 7 LUNA ZARATTINI BRANDÃO     PT         ELEITO POR QP                    100921
 8 LUANA DOS SANTOS ALVES SI… PSOL       ELEITO POR QP                     83262
 9 SANDRA REGINA CARBONE TAD… PL         ELEITO POR QP                     74511
10 SANDRA APARECIDA DE SOUZA… UNIÃO      ELEITO POR QP                     74192
# ℹ 1,006 more rows
# ℹ abbreviated name: ¹​SOMA_QT_VOTOS_NOMINAIS_VALIDOS

3.7 Filtrando dados com filter()

A função filter() é utilizada para filtrar linhas de um data frame com base em condições específicas.

Por exemplo, podemos filtrar apenas as pessoas candidatas de determinado partido (neste exemplo, da Rede). Para isso, utilizamos o operador de comparação == (igualdade):

dados |>
  filter(SG_PARTIDO == "REDE")
# A tibble: 8 × 51
  DT_GERACAO HH_GERACAO ANO_ELEICAO CD_TIPO_ELEICAO NM_TIPO_ELEICAO   NR_TURNO
  <chr>      <time>           <dbl>           <dbl> <chr>                <dbl>
1 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
2 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
3 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
4 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
5 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
6 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
7 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
8 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
# ℹ 45 more variables: CD_ELEICAO <dbl>, DS_ELEICAO <chr>, DT_ELEICAO <chr>,
#   TP_ABRANGENCIA <chr>, SG_UF <chr>, SG_UE <dbl>, NM_UE <chr>,
#   CD_CARGO <dbl>, DS_CARGO <chr>, SQ_CANDIDATO <dbl>, NR_CANDIDATO <dbl>,
#   NM_CANDIDATO <chr>, NM_URNA_CANDIDATO <chr>, NM_SOCIAL_CANDIDATO <chr>,
#   NR_CPF_CANDIDATO <dbl>, DS_EMAIL <chr>, CD_SITUACAO_CANDIDATURA <dbl>,
#   DS_SITUACAO_CANDIDATURA <chr>, TP_AGREMIACAO <chr>, NR_PARTIDO <dbl>,
#   SG_PARTIDO <chr>, NM_PARTIDO <chr>, NR_FEDERACAO <dbl>, …

Podemos também filtrar com mais de uma condição. Por exemplo, podemos filtrar apenas os resultados de candidatos(as) a vereador(a) que foram eleitos por quociente partidário (QP) ou por média. Neste caso, usamos o operador %in%, que permite verificar se um valor está presente em um vetor (c()) de valores.

dados_vereadores_eleitos <- dados |>
  filter(DS_SIT_TOT_TURNO %in% c("ELEITO POR QP", "ELEITO POR MÉDIA"))

dados_vereadores_eleitos
# A tibble: 55 × 51
   DT_GERACAO HH_GERACAO ANO_ELEICAO CD_TIPO_ELEICAO NM_TIPO_ELEICAO   NR_TURNO
   <chr>      <time>           <dbl>           <dbl> <chr>                <dbl>
 1 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 2 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 3 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 4 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 5 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 6 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 7 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 8 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 9 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
10 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
# ℹ 45 more rows
# ℹ 45 more variables: CD_ELEICAO <dbl>, DS_ELEICAO <chr>, DT_ELEICAO <chr>,
#   TP_ABRANGENCIA <chr>, SG_UF <chr>, SG_UE <dbl>, NM_UE <chr>,
#   CD_CARGO <dbl>, DS_CARGO <chr>, SQ_CANDIDATO <dbl>, NR_CANDIDATO <dbl>,
#   NM_CANDIDATO <chr>, NM_URNA_CANDIDATO <chr>, NM_SOCIAL_CANDIDATO <chr>,
#   NR_CPF_CANDIDATO <dbl>, DS_EMAIL <chr>, CD_SITUACAO_CANDIDATURA <dbl>,
#   DS_SITUACAO_CANDIDATURA <chr>, TP_AGREMIACAO <chr>, NR_PARTIDO <dbl>, …

A tabela filtrada tem 55 linhas, ou seja, foram eleitos 55 vereadores(as) na cidade de São Paulo nas eleições de 2024.

Podemos usar filtros com números também. Por exemplo: quantos(as) candidatos(as) a vereador(a) receberam 100 mil votos válidos ou mais?

dados_vereadores_eleitos |> 
  filter(SOMA_QT_VOTOS_NOMINAIS_VALIDOS >= 100000)
# A tibble: 7 × 51
  DT_GERACAO HH_GERACAO ANO_ELEICAO CD_TIPO_ELEICAO NM_TIPO_ELEICAO   NR_TURNO
  <chr>      <time>           <dbl>           <dbl> <chr>                <dbl>
1 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
2 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
3 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
4 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
5 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
6 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
7 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
# ℹ 45 more variables: CD_ELEICAO <dbl>, DS_ELEICAO <chr>, DT_ELEICAO <chr>,
#   TP_ABRANGENCIA <chr>, SG_UF <chr>, SG_UE <dbl>, NM_UE <chr>,
#   CD_CARGO <dbl>, DS_CARGO <chr>, SQ_CANDIDATO <dbl>, NR_CANDIDATO <dbl>,
#   NM_CANDIDATO <chr>, NM_URNA_CANDIDATO <chr>, NM_SOCIAL_CANDIDATO <chr>,
#   NR_CPF_CANDIDATO <dbl>, DS_EMAIL <chr>, CD_SITUACAO_CANDIDATURA <dbl>,
#   DS_SITUACAO_CANDIDATURA <chr>, TP_AGREMIACAO <chr>, NR_PARTIDO <dbl>,
#   SG_PARTIDO <chr>, NM_PARTIDO <chr>, NR_FEDERACAO <dbl>, …

Ao filtrar, podemos combinar várias condições utilizando os operadores lógicos (como o | (OU) e o ! (NEGAÇÃO)).

3.8 Adicionando ou modificando colunas com mutate()

A função mutate() é utilizada para adicionar novas colunas ou modificar colunas existentes em um data frame.

A sintaxe básica da função mutate() é:

base_de_dados |> 
  mutate(nome_da_nova_coluna = o_que_queremos_que_seja_salvo_nela)

A função mutate() também pode ser utilizada para modificar colunas existentes.

Por exemplo, podemos criar uma nova coluna chamada mil_votos_validos, que representa a quantidade de votos válidos dividida por 1000, para facilitar a leitura dos números:

dados_vereadores_eleitos |>
  mutate(
    mil_votos_validos = round(SOMA_QT_VOTOS_NOMINAIS_VALIDOS/1000, 2)
  ) 
# A tibble: 55 × 52
   DT_GERACAO HH_GERACAO ANO_ELEICAO CD_TIPO_ELEICAO NM_TIPO_ELEICAO   NR_TURNO
   <chr>      <time>           <dbl>           <dbl> <chr>                <dbl>
 1 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 2 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 3 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 4 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 5 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 6 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 7 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 8 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 9 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
10 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
# ℹ 45 more rows
# ℹ 46 more variables: CD_ELEICAO <dbl>, DS_ELEICAO <chr>, DT_ELEICAO <chr>,
#   TP_ABRANGENCIA <chr>, SG_UF <chr>, SG_UE <dbl>, NM_UE <chr>,
#   CD_CARGO <dbl>, DS_CARGO <chr>, SQ_CANDIDATO <dbl>, NR_CANDIDATO <dbl>,
#   NM_CANDIDATO <chr>, NM_URNA_CANDIDATO <chr>, NM_SOCIAL_CANDIDATO <chr>,
#   NR_CPF_CANDIDATO <dbl>, DS_EMAIL <chr>, CD_SITUACAO_CANDIDATURA <dbl>,
#   DS_SITUACAO_CANDIDATURA <chr>, TP_AGREMIACAO <chr>, NR_PARTIDO <dbl>, …

3.9 Agrupando dados com group_by()

A função group_by() é utilizada para agrupar os dados com base em uma ou mais colunas. Isso é especialmente útil quando queremos aplicar funções de resumo a cada grupo.

Por exemplo, podemos agrupar os dados por colunas relacionado aos partidos:

dados |>
  group_by(SG_PARTIDO, NM_PARTIDO) 
# A tibble: 1,016 × 51
# Groups:   SG_PARTIDO, NM_PARTIDO [29]
   DT_GERACAO HH_GERACAO ANO_ELEICAO CD_TIPO_ELEICAO NM_TIPO_ELEICAO   NR_TURNO
   <chr>      <time>           <dbl>           <dbl> <chr>                <dbl>
 1 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 2 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 3 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 4 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 5 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 6 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 7 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 8 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
 9 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
10 18/07/2025 12:30:11          2024               2 ELEIÇÃO ORDINÁRIA        1
# ℹ 1,006 more rows
# ℹ 45 more variables: CD_ELEICAO <dbl>, DS_ELEICAO <chr>, DT_ELEICAO <chr>,
#   TP_ABRANGENCIA <chr>, SG_UF <chr>, SG_UE <dbl>, NM_UE <chr>,
#   CD_CARGO <dbl>, DS_CARGO <chr>, SQ_CANDIDATO <dbl>, NR_CANDIDATO <dbl>,
#   NM_CANDIDATO <chr>, NM_URNA_CANDIDATO <chr>, NM_SOCIAL_CANDIDATO <chr>,
#   NR_CPF_CANDIDATO <dbl>, DS_EMAIL <chr>, CD_SITUACAO_CANDIDATURA <dbl>,
#   DS_SITUACAO_CANDIDATURA <chr>, TP_AGREMIACAO <chr>, NR_PARTIDO <dbl>, …

A função group_by() não altera os dados, mas prepara o data frame para que possamos aplicar funções de resumo a cada grupo. Portanto, ela é frequentemente utilizada em conjunto com a função summarise().

Obs: após usar a função group_by(), é importante lembrar de utilizar a função ungroup() para remover o agrupamento, caso não seja mais necessário. Isso pode evitar problemas em operações futuras.

3.10 Resumindo dados com summarise()

A função summarise() é utilizada para resumir os dados, calculando estatísticas agregadas. Ela é frequentemente utilizada em conjunto com a função group_by().

dados_por_partido <- dados |>
  # agrupando por colunas com informações dos partidos
  group_by(SG_PARTIDO, NM_PARTIDO) |> 
  summarise(
    # contando o número de candidatos por grupo
    quantidade_candidatos = n(),  
    quantidade_eleitos = sum(DS_SIT_TOT_TURNO %in% c("ELEITO POR QP", "ELEITO POR MÉDIA"), na.rm = TRUE),  # contando o número de candidatos eleitos
    
    media_votos_por_cand = mean(SOMA_QT_VOTOS_NOMINAIS_VALIDOS, na.rm = TRUE),  # calculando a média de votos válidos
    mediana_votos_por_cand = median(SOMA_QT_VOTOS_NOMINAIS_VALIDOS, na.rm = TRUE),  # calculando a mediana de votos válidos
    soma_votos = sum(SOMA_QT_VOTOS_NOMINAIS_VALIDOS, na.rm = TRUE)  # somando os votos válidos
  ) |> 
   # removendo o agrupamento
  ungroup() |> 
  arrange(desc(quantidade_eleitos), desc(soma_votos))
`summarise()` has grouped output by 'SG_PARTIDO'. You can override using the
`.groups` argument.
dados_por_partido
# A tibble: 29 × 7
   SG_PARTIDO   NM_PARTIDO              quantidade_candidatos quantidade_eleitos
   <chr>        <chr>                                   <int>              <int>
 1 PT           PARTIDO DOS TRABALHADO…                    48                  8
 2 UNIÃO        UNIÃO BRASIL                               46                  7
 3 MDB          MOVIMENTO DEMOCRÁTICO …                    57                  7
 4 PL           PARTIDO LIBERAL                            56                  7
 5 PODE         PODEMOS                                    56                  6
 6 PSOL         PARTIDO SOCIALISMO E L…                    48                  6
 7 PP           PROGRESSISTAS                              38                  4
 8 PSD          PARTIDO SOCIAL DEMOCRÁ…                    32                  3
 9 REPUBLICANOS REPUBLICANOS                               47                  2
10 PSB          PARTIDO SOCIALISTA BRA…                    56                  2
# ℹ 19 more rows
# ℹ 3 more variables: media_votos_por_cand <dbl>, mediana_votos_por_cand <dbl>,
#   soma_votos <dbl>
# Checando o número de eleitos
sum(dados_por_partido$quantidade_eleitos)
[1] 55

3.11 Extra: count()

A função count() é uma forma simplificada de usar group_by() e summarise(). Ela conta o número de ocorrências de cada grupo e retorna um data frame com as contagens. Por exemplo:

dados_vereadores_eleitos |>
  count(DS_GENERO) 
# A tibble: 2 × 2
  DS_GENERO     n
  <chr>     <int>
1 FEMININO     20
2 MASCULINO    35
dados_vereadores_eleitos |>
  count(DS_GRAU_INSTRUCAO) 
# A tibble: 3 × 2
  DS_GRAU_INSTRUCAO         n
  <chr>                 <int>
1 ENSINO MÉDIO COMPLETO     5
2 SUPERIOR COMPLETO        46
3 SUPERIOR INCOMPLETO       4
dados_vereadores_eleitos |>
  count(DS_COR_RACA) 
# A tibble: 4 × 2
  DS_COR_RACA     n
  <chr>       <int>
1 AMARELA         1
2 BRANCA         38
3 PARDA          10
4 PRETA           6

3.12 Escrevendo dados com write_csv() ou writexl::write_xlsx()

Podemos salvar o resultado em um arquivo CSV ou Excel, utilizando as funções readr::write_csv() ou writexl::write_xlsx():

write_csv(dados_por_partido,
          "dados/tab-dados_por_partido.csv")

writexl::write_xlsx(dados_por_partido,
                    "dados/tab-dados_por_partido.xlsx")