4  Análise exploratória de dados - Parte 2

Nesta segunda parte da análise exploratória de dados, vamos conhecer as funções mais importantes do pacote dplyr para manipulação de dados.

4.1 Carregando pacotes

library(tidyverse)

4.2 Carregando os dados

Vamos continuar trabalhando nos dados da CETESB, que já foram carregados na primeira parte da análise exploratória (aula passada). Caso você não tenha feito isso, recomendo que você siga as instruções da aula anterior antes de continuar a aula de hoje.

dados_cetesb <- read_csv("dados/dados-cetesb-2022.csv")
Rows: 645 Columns: 12
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (2): uf, municipio
dbl (10): ano, ugrhi, codigo_ibge, populacao_urbana, atendimento_coleta_porc...

ℹ 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.

Outra forma de importar os dados é utilizando o link direto do repositório do GitHub onde os dados estão armazenados. Você pode fazer isso utilizando a função read_csv() do pacote readr:

dados_cetesb <- read_csv("https://raw.githubusercontent.com/beatrizmilz/ESHT011-21-analise-dados-planejamento-territorial/refs/heads/main/dados/dados-cetesb-2022.csv")

A função glimpse() do pacote dplyr, que conhecemos na aula passada, é uma forma rápida de visualizar a estrutura dos dados. Ela nos mostra o nome das colunas, o tipo de dado de cada coluna e os primeiros valores de cada coluna:

glimpse(dados_cetesb)
Rows: 645
Columns: 12
$ ano                           <dbl> 2022, 2022, 2022, 2022, 2022, 2022, 2022…
$ uf                            <chr> "SP", "SP", "SP", "SP", "SP", "SP", "SP"…
$ ugrhi                         <dbl> 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2…
$ municipio                     <chr> "Campos do Jordão", "Santo Antônio do Pi…
$ codigo_ibge                   <dbl> 3509700, 3548203, 3548609, 3502507, 3503…
$ populacao_urbana              <dbl> 52384, 4067, 5251, 35684, 1844, 2619, 88…
$ atendimento_coleta_porc       <dbl> 52.6, 46.7, 98.0, 70.0, 95.6, 100.0, 88.…
$ atendimento_tratamento_porc   <dbl> 100.0, 100.0, 100.0, 0.0, 95.6, 0.0, 100…
$ eficiencia                    <dbl> 93.0, 80.0, 91.3, 0.0, 99.0, 0.0, 75.0, …
$ carga_poluidora_potencial     <dbl> 2829, 220, 284, 1927, 100, 141, 476, 442…
$ carga_poluidora_remancescente <dbl> 1445, 138, 30, 1927, 9, 141, 161, 1858, …
$ ictem                         <dbl> 5.97, 4.63, 9.97, 1.55, 9.86, 1.50, 7.61…

4.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_cetesb |> 
  glimpse()
Rows: 645
Columns: 12
$ ano                           <dbl> 2022, 2022, 2022, 2022, 2022, 2022, 2022…
$ uf                            <chr> "SP", "SP", "SP", "SP", "SP", "SP", "SP"…
$ ugrhi                         <dbl> 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2…
$ municipio                     <chr> "Campos do Jordão", "Santo Antônio do Pi…
$ codigo_ibge                   <dbl> 3509700, 3548203, 3548609, 3502507, 3503…
$ populacao_urbana              <dbl> 52384, 4067, 5251, 35684, 1844, 2619, 88…
$ atendimento_coleta_porc       <dbl> 52.6, 46.7, 98.0, 70.0, 95.6, 100.0, 88.…
$ atendimento_tratamento_porc   <dbl> 100.0, 100.0, 100.0, 0.0, 95.6, 0.0, 100…
$ eficiencia                    <dbl> 93.0, 80.0, 91.3, 0.0, 99.0, 0.0, 75.0, …
$ carga_poluidora_potencial     <dbl> 2829, 220, 284, 1927, 100, 141, 476, 442…
$ carga_poluidora_remancescente <dbl> 1445, 138, 30, 1927, 9, 141, 161, 1858, …
$ ictem                         <dbl> 5.97, 4.63, 9.97, 1.55, 9.86, 1.50, 7.61…

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!

4.4 Principais funções 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:

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

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

  • mutate(): adiciona ou modifica colunas.

  • arrange(): ordena as linhas de um data frame com base em uma ou mais 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 listados no final da aula para aprender mais sobre cada função e suas possibilidades.

4.5 Filtrando dados com filter()

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

Por exemplo, podemos filtrar os dados da CETESB para mostrar apenas os municípios que possuem uma população urbana maior que 1 milhão de habitantes:

dados_cetesb |>
  filter(populacao_urbana > 1000000)
# A tibble: 3 × 12
    ano uf    ugrhi municipio codigo_ibge populacao_urbana
  <dbl> <chr> <dbl> <chr>           <dbl>            <dbl>
1  2022 SP        5 Campinas      3509502          1202203
2  2022 SP        6 Guarulhos     3518800          1404694
3  2022 SP        6 São Paulo     3550308         12284940
# ℹ 6 more variables: atendimento_coleta_porc <dbl>,
#   atendimento_tratamento_porc <dbl>, eficiencia <dbl>,
#   carga_poluidora_potencial <dbl>, carga_poluidora_remancescente <dbl>,
#   ictem <dbl>

Podemos também filtrar as linhas dos municípios do Grande ABC. Neste caso, é mais fácil criar um vetor com os nomes dos municípios, e utilizar o operador %in% para filtrar os dados:

municipios_grande_abc <- c("São Caetano do Sul", "São Bernardo do Campo", "Diadema", "Santo André", "Mauá", "Ribeirão Pires", "Rio Grande da Serra")

dados_cetesb |>
  filter(municipio %in% municipios_grande_abc)
# A tibble: 7 × 12
    ano uf    ugrhi municipio             codigo_ibge populacao_urbana
  <dbl> <chr> <dbl> <chr>                       <dbl>            <dbl>
1  2022 SP        6 Diadema                   3513801           429550
2  2022 SP        6 Mauá                      3529401           481725
3  2022 SP        6 Ribeirão Pires            3543303           125238
4  2022 SP        6 Rio Grande da Serra       3544103            52009
5  2022 SP        6 Santo André               3547809           723889
6  2022 SP        6 São Bernardo do Campo     3548708           835657
7  2022 SP        6 São Caetano do Sul        3548807           162763
# ℹ 6 more variables: atendimento_coleta_porc <dbl>,
#   atendimento_tratamento_porc <dbl>, eficiencia <dbl>,
#   carga_poluidora_potencial <dbl>, carga_poluidora_remancescente <dbl>,
#   ictem <dbl>

Podemos também consultar quais são os municípios que coletam 100% do esgoto produzido:

dados_cetesb |> 
  filter(atendimento_coleta_porc == 100)
# A tibble: 253 × 12
     ano uf    ugrhi municipio          codigo_ibge populacao_urbana
   <dbl> <chr> <dbl> <chr>                    <dbl>            <dbl>
 1  2022 SP        2 Areias                 3503505             2619
 2  2022 SP        2 Caçapava               3508504            81929
 3  2022 SP        2 Cachoeira Paulista     3508603            27623
 4  2022 SP        2 Jambeiro               3524907             3269
 5  2022 SP        2 Pindamonhangaba        3538006           165703
 6  2022 SP        2 Taubaté                3554102           313898
 7  2022 SP        4 Altinópolis            3501004            14172
 8  2022 SP        4 Caconde                3508702            12975
 9  2022 SP        4 Casa Branca            3510807            25075
10  2022 SP        4 Jardinópolis           3525102            43706
# ℹ 243 more rows
# ℹ 6 more variables: atendimento_coleta_porc <dbl>,
#   atendimento_tratamento_porc <dbl>, eficiencia <dbl>,
#   carga_poluidora_potencial <dbl>, carga_poluidora_remancescente <dbl>,
#   ictem <dbl>

Destes, podemos filtrar os que tratem 100% do esgoto coletado:

dados_cetesb |> 
  filter(atendimento_coleta_porc == 100, atendimento_tratamento_porc == 100)
# A tibble: 218 × 12
     ano uf    ugrhi municipio               codigo_ibge populacao_urbana
   <dbl> <chr> <dbl> <chr>                         <dbl>            <dbl>
 1  2022 SP        2 Cachoeira Paulista          3508603            27623
 2  2022 SP        2 Jambeiro                    3524907             3269
 3  2022 SP        2 Pindamonhangaba             3538006           165703
 4  2022 SP        2 Taubaté                     3554102           313898
 5  2022 SP        4 Altinópolis                 3501004            14172
 6  2022 SP        4 Santa Cruz da Esperança     3546256             1467
 7  2022 SP        4 Serrana                     3551504            45677
 8  2022 SP        4 Tambaú                      3553302            20663
 9  2022 SP        5 Corumbataí                  3512704             2200
10  2022 SP        5 Holambra                    3519055            11303
# ℹ 208 more rows
# ℹ 6 more variables: atendimento_coleta_porc <dbl>,
#   atendimento_tratamento_porc <dbl>, eficiencia <dbl>,
#   carga_poluidora_potencial <dbl>, carga_poluidora_remancescente <dbl>,
#   ictem <dbl>

As possibilidades são muitas! Podemos combinar várias condições utilizando os operadores lógicos (como o | (OU) e o ! (NEGAÇÃO).

4.6 Selecionando colunas com select()

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

Por exemplo, podemos selecionar apenas as colunas municipio, populacao_urbana e atendimento_coleta_porc dos dados da CETESB:

dados_cetesb |>
  select(municipio, populacao_urbana, atendimento_coleta_porc)
# A tibble: 645 × 3
   municipio               populacao_urbana atendimento_coleta_porc
   <chr>                              <dbl>                   <dbl>
 1 Campos do Jordão                   52384                    52.6
 2 Santo Antônio do Pinhal             4067                    46.7
 3 São Bento do Sapucaí                5251                    98  
 4 Aparecida                          35684                    70  
 5 Arapeí                              1844                    95.6
 6 Areias                              2619                   100  
 7 Bananal                             8808                    88.1
 8 Caçapava                           81929                   100  
 9 Cachoeira Paulista                 27623                   100  
10 Canas                               4890                    84.6
# ℹ 635 more rows

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

dados_cetesb |>
  select(-ano, -uf)
# A tibble: 645 × 10
   ugrhi municipio           codigo_ibge populacao_urbana atendimento_coleta_p…¹
   <dbl> <chr>                     <dbl>            <dbl>                  <dbl>
 1     1 Campos do Jordão        3509700            52384                   52.6
 2     1 Santo Antônio do P…     3548203             4067                   46.7
 3     1 São Bento do Sapuc…     3548609             5251                   98  
 4     2 Aparecida               3502507            35684                   70  
 5     2 Arapeí                  3503158             1844                   95.6
 6     2 Areias                  3503505             2619                  100  
 7     2 Bananal                 3504909             8808                   88.1
 8     2 Caçapava                3508504            81929                  100  
 9     2 Cachoeira Paulista      3508603            27623                  100  
10     2 Canas                   3509957             4890                   84.6
# ℹ 635 more rows
# ℹ abbreviated name: ¹​atendimento_coleta_porc
# ℹ 5 more variables: atendimento_tratamento_porc <dbl>, eficiencia <dbl>,
#   carga_poluidora_potencial <dbl>, carga_poluidora_remancescente <dbl>,
#   ictem <dbl>

4.7 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)

Por exemplo, podemos criar uma coluna nova chamada populacao_urbana_mil que representa a população urbana em mil habitantes:

dados_cetesb |>
  # selecionando as colunas municipio e populacao_urbana
  # para facilitar a visualização
  select(municipio, populacao_urbana) |>
  mutate(populacao_urbana_mil = populacao_urbana / 1000)
# A tibble: 645 × 3
   municipio               populacao_urbana populacao_urbana_mil
   <chr>                              <dbl>                <dbl>
 1 Campos do Jordão                   52384                52.4 
 2 Santo Antônio do Pinhal             4067                 4.07
 3 São Bento do Sapucaí                5251                 5.25
 4 Aparecida                          35684                35.7 
 5 Arapeí                              1844                 1.84
 6 Areias                              2619                 2.62
 7 Bananal                             8808                 8.81
 8 Caçapava                           81929                81.9 
 9 Cachoeira Paulista                 27623                27.6 
10 Canas                               4890                 4.89
# ℹ 635 more rows

A função mutate() também pode ser utilizada para modificar colunas existentes. Por exemplo, podemos mudar a classe de algumas colunas:

dados_cetesb |>
  mutate(
    ugrhi = as.character(ugrhi),  # convertendo ugrhi para character
    codigo_ibge = as.character(codigo_ibge)  # convertendo codigo_ibge para character
  )
# A tibble: 645 × 12
     ano uf    ugrhi municipio               codigo_ibge populacao_urbana
   <dbl> <chr> <chr> <chr>                   <chr>                  <dbl>
 1  2022 SP    1     Campos do Jordão        3509700                52384
 2  2022 SP    1     Santo Antônio do Pinhal 3548203                 4067
 3  2022 SP    1     São Bento do Sapucaí    3548609                 5251
 4  2022 SP    2     Aparecida               3502507                35684
 5  2022 SP    2     Arapeí                  3503158                 1844
 6  2022 SP    2     Areias                  3503505                 2619
 7  2022 SP    2     Bananal                 3504909                 8808
 8  2022 SP    2     Caçapava                3508504                81929
 9  2022 SP    2     Cachoeira Paulista      3508603                27623
10  2022 SP    2     Canas                   3509957                 4890
# ℹ 635 more rows
# ℹ 6 more variables: atendimento_coleta_porc <dbl>,
#   atendimento_tratamento_porc <dbl>, eficiencia <dbl>,
#   carga_poluidora_potencial <dbl>, carga_poluidora_remancescente <dbl>,
#   ictem <dbl>

4.8 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 da CETESB pela coluna carga_poluidora_remancescente, em ordem crescente:

dados_cetesb |>
  arrange(carga_poluidora_remancescente)
# A tibble: 645 × 12
     ano uf    ugrhi municipio              codigo_ibge populacao_urbana
   <dbl> <chr> <dbl> <chr>                        <dbl>            <dbl>
 1  2022 SP       14 Ribeirão Grande            3543253             2427
 2  2022 SP       13 Trabiju                    3554755             1609
 3  2022 SP       21 Borá                       3507209              653
 4  2022 SP       15 Turmalina                  3555307             1186
 5  2022 SP        2 Jambeiro                   3524907             3269
 6  2022 SP       18 Santa Salete               3547650              882
 7  2022 SP       18 Santana da Ponte Pensa     3547205              968
 8  2022 SP       15 Mesópolis                  3529658             1481
 9  2022 SP       18 Nova Canaã Paulista        3532843              759
10  2022 SP       19 Turiúba                    3555208             1657
# ℹ 635 more rows
# ℹ 6 more variables: atendimento_coleta_porc <dbl>,
#   atendimento_tratamento_porc <dbl>, eficiencia <dbl>,
#   carga_poluidora_potencial <dbl>, carga_poluidora_remancescente <dbl>,
#   ictem <dbl>

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

dados_cetesb |>
  arrange(desc(populacao_urbana))
# A tibble: 645 × 12
     ano uf    ugrhi municipio             codigo_ibge populacao_urbana
   <dbl> <chr> <dbl> <chr>                       <dbl>            <dbl>
 1  2022 SP        6 São Paulo                 3550308         12284940
 2  2022 SP        6 Guarulhos                 3518800          1404694
 3  2022 SP        5 Campinas                  3509502          1202203
 4  2022 SP        6 São Bernardo do Campo     3548708           835657
 5  2022 SP        6 Santo André               3547809           723889
 6  2022 SP        2 São José dos Campos       3549904           722310
 7  2022 SP        4 Ribeirão Preto            3543402           718072
 8  2022 SP        6 Osasco                    3534401           701428
 9  2022 SP       10 Sorocaba                  3552205           688252
10  2022 SP        6 Mauá                      3529401           481725
# ℹ 635 more rows
# ℹ 6 more variables: atendimento_coleta_porc <dbl>,
#   atendimento_tratamento_porc <dbl>, eficiencia <dbl>,
#   carga_poluidora_potencial <dbl>, carga_poluidora_remancescente <dbl>,
#   ictem <dbl>

4.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 da CETESB pela coluna ugrhi (Unidade de Gerenciamento de Recursos Hídricos) e calcular a soma da população urbana para cada UGRHI:

dados_cetesb |>
  group_by(ugrhi) 
# A tibble: 645 × 12
# Groups:   ugrhi [22]
     ano uf    ugrhi municipio               codigo_ibge populacao_urbana
   <dbl> <chr> <dbl> <chr>                         <dbl>            <dbl>
 1  2022 SP        1 Campos do Jordão            3509700            52384
 2  2022 SP        1 Santo Antônio do Pinhal     3548203             4067
 3  2022 SP        1 São Bento do Sapucaí        3548609             5251
 4  2022 SP        2 Aparecida                   3502507            35684
 5  2022 SP        2 Arapeí                      3503158             1844
 6  2022 SP        2 Areias                      3503505             2619
 7  2022 SP        2 Bananal                     3504909             8808
 8  2022 SP        2 Caçapava                    3508504            81929
 9  2022 SP        2 Cachoeira Paulista          3508603            27623
10  2022 SP        2 Canas                       3509957             4890
# ℹ 635 more rows
# ℹ 6 more variables: atendimento_coleta_porc <dbl>,
#   atendimento_tratamento_porc <dbl>, eficiencia <dbl>,
#   carga_poluidora_potencial <dbl>, carga_poluidora_remancescente <dbl>,
#   ictem <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().

4.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().

Como vimos na aula anterior, a função summary() nos dá um resumo de estatísticas descritivas para todas as colunas. Porém, podemos querer calcular estatísticas descritivas apenas para algum subconjunto dos dados.

Imagine que queremos calcular algumas estatísticas descritivas considerando cada UGRHI (Unidade de Gerenciamento de Recursos Hídricos) separadamente. Podemos fazer isso utilizando as funções group_by() e summarise().

estatisticas_descritivas <- dados_cetesb |>
  # agrupar os dados pela coluna ugrhi
  group_by(ugrhi) |>
  # calcular estatísticas descritivas para cada grupo
  summarise(
    quantidade_municipios = n(),
    soma_populacao_urbana = sum(populacao_urbana),
    media_ictem = mean(ictem) |> round(2),
    mediana_ictem = median(ictem) |> round(2),
    desvio_padrao_ictem = sd(ictem) |> round(2)
  )

knitr::kable(estatisticas_descritivas)
ugrhi quantidade_municipios soma_populacao_urbana media_ictem mediana_ictem desvio_padrao_ictem
1 3 61702 6.86 5.97 2.78
2 34 2124413 5.87 6.98 3.30
3 4 337159 5.10 4.66 1.74
4 23 1215586 7.09 8.12 2.83
5 57 5737151 7.10 7.85 2.99
6 34 21626154 4.93 5.03 2.39
7 9 1893370 5.01 5.09 1.22
8 22 707923 9.18 9.98 1.34
9 38 1542781 6.91 7.64 3.02
10 33 1937230 7.05 7.10 2.66
11 23 273446 7.10 7.09 1.87
12 12 346186 7.92 8.45 2.59
13 34 1608773 7.94 8.08 2.29
14 34 631467 8.01 8.20 1.84
15 64 1289129 8.77 9.89 1.66
16 33 520262 8.36 9.70 2.24
17 42 666615 8.88 9.75 1.23
18 25 212661 9.01 10.00 1.63
19 42 772089 8.31 8.15 1.54
20 32 348271 8.69 8.57 1.34
21 26 444578 8.96 9.70 1.80
22 21 470161 9.09 9.70 1.01

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

write_csv(estatisticas_descritivas,
          "dados/estatisticas-descritivas-ugrhi.csv")

writexl::write_xlsx(estatisticas_descritivas,
                    "dados/estatisticas-descritivas-ugrhi.xlsx")

4.11 Unindo tabelas com left_join()

A função left_join() é utilizada para unir duas tabelas com base em uma ou mais colunas em comum (chamada de chave - key).

Para este exemplo, vamos importar uma tabela que contém informações sobre o IDH (Índice de Desenvolvimento Humano) dos municípios de São Paulo, referente ao ano de 2010. Esses dados são baseados no Censo, mas ainda não temos o IDH calculado para o ano de 2022.

dados_idhm <- read_csv("https://raw.githubusercontent.com/beatrizmilz/ESHT011-21-analise-dados-planejamento-territorial/refs/heads/main/praticas/dados/idhm_sp_2010.csv")
Rows: 645 Columns: 15
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (3): muni_nm, uf_sigla, regiao_nm
dbl (12): ano, muni_id, idhm, idhm_e, idhm_l, idhm_r, espvida, rdpc, gini, p...

ℹ 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.

Para fazer o join, precisamos garantir que as colunas que vamos utilizar como chave estejam no mesmo formato. Neste caso, vamos utilizar a coluna referente ao código do IBGE como chave para unir as duas tabelas:

names(dados_idhm)
 [1] "ano"       "muni_id"   "muni_nm"   "uf_sigla"  "regiao_nm" "idhm"     
 [7] "idhm_e"    "idhm_l"    "idhm_r"    "espvida"   "rdpc"      "gini"     
[13] "pop"       "lat"       "lon"      
names(dados_cetesb)
 [1] "ano"                           "uf"                           
 [3] "ugrhi"                         "municipio"                    
 [5] "codigo_ibge"                   "populacao_urbana"             
 [7] "atendimento_coleta_porc"       "atendimento_tratamento_porc"  
 [9] "eficiencia"                    "carga_poluidora_potencial"    
[11] "carga_poluidora_remancescente" "ictem"                        

É importante que a variável que usaremos como chave esteja no mesmo formato nas duas tabelas. Usamos a função class() para verificar o tipo de dado de cada coluna:

class(dados_cetesb$codigo_ibge)
[1] "numeric"
class(dados_idhm$muni_id)
[1] "numeric"

Obs: caso as colunas não estejam no mesmo formato, podemos utilizar a função mutate() para alterar o tipo de dado de uma das colunas, junto com funções como as.character() ou as.numeric(), dependendo da classe de dado que queremos.

Agora podemos unir as duas tabelas utilizando a função left_join(). Essa função irá manter todas as linhas da tabela da esquerda (dados_cetesb) e adicionar as colunas da tabela da direita (dados_idhm) onde houver correspondência na chave especificada.

dados_unidos <- left_join(
  # tabela da esquerda
  dados_cetesb, 
  # tabela da direita
  dados_idhm, 
  # o argumento `by` especifica as colunas que serão utilizadas como chave para o join
  by = c("codigo_ibge" = "muni_id")
  )

A nova tabela dados_unidos agora contém todas as colunas de ambas as tabelas, com os dados do IDH adicionados aos municípios correspondentes. Se um município não tiver um valor correspondente na tabela de IDH, as colunas relacionadas ao IDH terão valores NA.

glimpse(dados_unidos)
Rows: 645
Columns: 26
$ ano.x                         <dbl> 2022, 2022, 2022, 2022, 2022, 2022, 2022…
$ uf                            <chr> "SP", "SP", "SP", "SP", "SP", "SP", "SP"…
$ ugrhi                         <dbl> 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2…
$ municipio                     <chr> "Campos do Jordão", "Santo Antônio do Pi…
$ codigo_ibge                   <dbl> 3509700, 3548203, 3548609, 3502507, 3503…
$ populacao_urbana              <dbl> 52384, 4067, 5251, 35684, 1844, 2619, 88…
$ atendimento_coleta_porc       <dbl> 52.6, 46.7, 98.0, 70.0, 95.6, 100.0, 88.…
$ atendimento_tratamento_porc   <dbl> 100.0, 100.0, 100.0, 0.0, 95.6, 0.0, 100…
$ eficiencia                    <dbl> 93.0, 80.0, 91.3, 0.0, 99.0, 0.0, 75.0, …
$ carga_poluidora_potencial     <dbl> 2829, 220, 284, 1927, 100, 141, 476, 442…
$ carga_poluidora_remancescente <dbl> 1445, 138, 30, 1927, 9, 141, 161, 1858, …
$ ictem                         <dbl> 5.97, 4.63, 9.97, 1.55, 9.86, 1.50, 7.61…
$ ano.y                         <dbl> 2010, 2010, 2010, 2010, 2010, 2010, 2010…
$ muni_nm                       <chr> "CAMPOS DO JORDÃO", "SANTO ANTÔNIO DO PI…
$ uf_sigla                      <chr> "SP", "SP", "SP", "SP", "SP", "SP", "SP"…
$ regiao_nm                     <chr> "Sudeste", "Sudeste", "Sudeste", "Sudest…
$ idhm                          <dbl> 0.749, 0.706, 0.720, 0.755, 0.680, 0.697…
$ idhm_e                        <dbl> 0.648, 0.632, 0.638, 0.706, 0.612, 0.672…
$ idhm_l                        <dbl> 0.852, 0.812, 0.812, 0.828, 0.812, 0.803…
$ idhm_r                        <dbl> 0.761, 0.685, 0.719, 0.735, 0.634, 0.627…
$ espvida                       <dbl> 76.10, 73.69, 73.69, 74.67, 73.72, 73.18…
$ rdpc                          <dbl> 911.40, 569.08, 701.89, 775.17, 414.19, …
$ gini                          <dbl> 0.59, 0.47, 0.55, 0.46, 0.39, 0.44, 0.51…
$ pop                           <dbl> 47287, 6450, 10370, 34630, 2481, 3632, 1…
$ lat                           <dbl> -22.739, -22.827, -22.689, -22.847, -22.…
$ lon                           <dbl> -45.591, -45.663, -45.731, -45.230, -44.…

Este caso é um exemplo de um join bem simples, onde temos uma chave única em cada tabela. No entanto, existem outros tipos de joins, como inner_join(), right_join(), full_join(), que podem ser utilizados dependendo da situação.

4.12 Materiais complementares