Tópico IV - Manipulação de Dados II
2024-04-17
R
.Para realizar joins, utilizamos o conceito de chaves, variáveis que identificam cada observação de maneira única. Alguns exemplos:
Em muitas situações, no entanto, as chaves de identificação das unidades de observação estão restritas a bases de dados não públicas. Além disso, nos últimos anos foi necessária a adequação à Lei Geral de Proteção de dados (LGPD).
Para entender o conceito de joins, utilizaremos a representação gráfica baseada no livro R for Data Science. Considere dois bancos de dados, com a chave dos indivíduos e o valor de uma variável
O pacote dplyr
possui funções que possibilitam realizar o joins (ou merge) de duas bases de dados. Podemos utilizar o diagrama de Venn para ter uma visão geral dos diferentes tipos:
As principais funções utilizadas são:
inner_join()
left_join()
right_join()
full_join()
inner_join()
As principais funções utilizadas são:
inner_join()
: retorna apenas as linhas com correspondências nas duas bases.left_join()
right_join()
full_join()
inner_join()
O resultado do inner_join()
é uma nova base que contem as chaves comuns nas duas bases e os valores da variáveis na base de dados x e na base de dados y
inner_join()
Para um exemplo mais concreto, utilizaremos dois bancos de dados: um com informações sobre os funcionários de uma empresa e outro com a remuneração média para cada cargo.
# Informacoes sobre homicidios por genero
homicidios <- tibble(
codigo_ibge = c("3550308", "3304557", "3106200", "2927408", "5300108",
"4106902", "2611606", "2304400", "1302603", "4314902"),
municipio = c("São Paulo", "Rio de Janeiro", "Belo Horizonte", "Salvador",
"Brasília", "Curitiba", "Recife", "Fortaleza", "Manaus",
"Porto Alegre"),
homicidios_homem = c(200, 150, 80, 120, 90, 60, 50, 70, 40, 55),
homicidios_mulher = c(40, 30, 20, 35, 25, 15, 10, 20, 12, 18)
)
# Criando tabela com informações sobre a população dos municípios
populacao <- tibble(
codigo_ibge = c("3550308", "3304557", "3106200", "2927408", "5300108",
"4106902", "2611606", "2304400", "1302603", "4314902"),
populacao = c(12000000, 6500000, 2500000, 2900000, 3100000, 1900000,
1600000, 2700000, 2200000, 1500000)
)
inner_join()
# Dados de homicidios
homicidios
## # A tibble: 10 × 4
## codigo_ibge municipio homicidios_homem homicidios_mulher
## <chr> <chr> <dbl> <dbl>
## 1 3550308 São Paulo 200 40
## 2 3304557 Rio de Janeiro 150 30
## 3 3106200 Belo Horizonte 80 20
## 4 2927408 Salvador 120 35
## 5 5300108 Brasília 90 25
## 6 4106902 Curitiba 60 15
## 7 2611606 Recife 50 10
## 8 2304400 Fortaleza 70 20
## 9 1302603 Manaus 40 12
## 10 4314902 Porto Alegre 55 18
# Dados de populacao
populacao
## # A tibble: 10 × 2
## codigo_ibge populacao
## <chr> <dbl>
## 1 3550308 12000000
## 2 3304557 6500000
## 3 3106200 2500000
## 4 2927408 2900000
## 5 5300108 3100000
## 6 4106902 1900000
## 7 2611606 1600000
## 8 2304400 2700000
## 9 1302603 2200000
## 10 4314902 1500000
inner_join()
O inner_join()
cria uma base retornando apenas as ocorrências (linhas) que possuem chaves iguais nos dois conjuntos:
inner_join(homicidios, populacao, by = "codigo_ibge")
## # A tibble: 10 × 5
## codigo_ibge municipio homicidios_homem homicidios_mulher populacao
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 3550308 São Paulo 200 40 12000000
## 2 3304557 Rio de Janeiro 150 30 6500000
## 3 3106200 Belo Horizonte 80 20 2500000
## 4 2927408 Salvador 120 35 2900000
## 5 5300108 Brasília 90 25 3100000
## 6 4106902 Curitiba 60 15 1900000
## 7 2611606 Recife 50 10 1600000
## 8 2304400 Fortaleza 70 20 2700000
## 9 1302603 Manaus 40 12 2200000
## 10 4314902 Porto Alegre 55 18 1500000
Suponha que o nome das variáveis utilizadas para fazer o join são distintas, conforme o exemplo a seguir. Como realizar o inner_join()
neste caso?
inner_join()
inner_join
desconsiderar do resultado as informações que não tiveram matching.Como vimos, o inner_join()
não leva em consideração as linhas onde as chaves não coincidem. Se quisermos manter todas as informações, utilizamos o conceito de outer joins. Existem três tipos básicos:
left_join()
right_join()
full_join()
Para os exemplos a seguir, considere as seguintes bases de dados:
# Base de dados pacientes
pacientes <- tibble(
id_paciente = 1:9,
nome = c("A.A.M", "S.S.G.F", "T.I.A", "L.O.S.M", "Y.Q.W",
"F.A", "T.B.N", "J.J.L", "M.S.S"),
exame_a = c(3.8, 3.8, 3.9, 4.0, 4.4, 3.8, 3.7, 3.6, 4.0),
exame_b = c(89.9, 89.9, 99.8, 99.9, 100.0, 89.9,
109.9, 109.9, 110.0),
exame_c = c(0, 1, 1, 0, 1, 1, 0, 0, 1)
)
# Base de dados tratamento
tratamento <- tibble(
id_paciente = c(1, 4, 5, 7, 8, 11, 15, 25),
medicamento = c("A", "B", "A", "B", "A", "A", "B", "B")
)
# Visualizando pacientes
pacientes
## # A tibble: 9 × 5
## id_paciente nome exame_a exame_b exame_c
## <int> <chr> <dbl> <dbl> <dbl>
## 1 1 A.A.M 3.8 89.9 0
## 2 2 S.S.G.F 3.8 89.9 1
## 3 3 T.I.A 3.9 99.8 1
## 4 4 L.O.S.M 4 99.9 0
## 5 5 Y.Q.W 4.4 100 1
## 6 6 F.A 3.8 89.9 1
## 7 7 T.B.N 3.7 110. 0
## 8 8 J.J.L 3.6 110. 0
## 9 9 M.S.S 4 110 1
left_join()
As principais funções utilizadas são:
inner_join()
left_join()
: mantém todas as observações do banco x
(o banco do lado esquerdo)right_join()
full_join()
left_join()
A função left_join()
preserva todas as observações do lado esquerdo (x
) e remove as informações do lado direito (y
) que não possuem correspondência.
x
.left_join()
Para preservar todos os pacientes e desprezar os registros de tratamento que não correspondem a pacientes hospitalizados, fazemos:
# Left join do dplyr
left_join(pacientes, tratamento, join_by(id_paciente))
## # A tibble: 9 × 6
## id_paciente nome exame_a exame_b exame_c medicamento
## <dbl> <chr> <dbl> <dbl> <dbl> <chr>
## 1 1 A.A.M 3.8 89.9 0 A
## 2 2 S.S.G.F 3.8 89.9 1 <NA>
## 3 3 T.I.A 3.9 99.8 1 <NA>
## 4 4 L.O.S.M 4 99.9 0 B
## 5 5 Y.Q.W 4.4 100 1 A
## 6 6 F.A 3.8 89.9 1 <NA>
## 7 7 T.B.N 3.7 110. 0 B
## 8 8 J.J.L 3.6 110. 0 A
## 9 9 M.S.S 4 110 1 <NA>
right_join()
As principais funções são:
y
(o banco do lado direito)right_join()
O comando right_join()
preserva todas as observações do lado direito e remove as informações do lado esquerdo que não possuem correspondência.
y
.right_join()
Para preservar todos as linhas do conjunto da direita (tratamento) e desprezar os pacientes sem correspondência de chave, fazemos:
# Right join do dplyr
right_join(pacientes, tratamento, join_by(id_paciente))
## # A tibble: 8 × 6
## id_paciente nome exame_a exame_b exame_c medicamento
## <dbl> <chr> <dbl> <dbl> <dbl> <chr>
## 1 1 A.A.M 3.8 89.9 0 A
## 2 4 L.O.S.M 4 99.9 0 B
## 3 5 Y.Q.W 4.4 100 1 A
## 4 7 T.B.N 3.7 110. 0 B
## 5 8 J.J.L 3.6 110. 0 A
## 6 11 <NA> NA NA NA A
## 7 15 <NA> NA NA NA B
## 8 25 <NA> NA NA NA B
full_join()
As principais funções são:
inner_join()
left_join()
right_join()
full_join()
: mantem todas as observações dos bancos x
e y
full_join()
O comando full_join()
preserva todas as observações de ambos os bancos
NA
.full_join()
Para preservar todos os registros de ambos os conjuntos de dados, fazemos:
# Full join do dplyr
full_join(pacientes, tratamento, join_by(id_paciente))
## # A tibble: 12 × 6
## id_paciente nome exame_a exame_b exame_c medicamento
## <dbl> <chr> <dbl> <dbl> <dbl> <chr>
## 1 1 A.A.M 3.8 89.9 0 A
## 2 2 S.S.G.F 3.8 89.9 1 <NA>
## 3 3 T.I.A 3.9 99.8 1 <NA>
## 4 4 L.O.S.M 4 99.9 0 B
## 5 5 Y.Q.W 4.4 100 1 A
## 6 6 F.A 3.8 89.9 1 <NA>
## 7 7 T.B.N 3.7 110. 0 B
## 8 8 J.J.L 3.6 110. 0 A
## 9 9 M.S.S 4 110 1 <NA>
## 10 11 <NA> NA NA NA A
## 11 15 <NA> NA NA NA B
## 12 25 <NA> NA NA NA B
# Cadastro de clientes
clientes <- tibble(
id_cliente = c(1, 2, 3, 4, 5),
nome_cliente = c("João", "Maria", "Pedro", "Ana", "Luiza"),
idade_cliente = c(30, 25, 40, 35, 28),
sexo = c("M", "F", "M", "F", "F")
)
# Historico de compras
compras <- tibble(
id_cliente = c(1, 2, 3, 4, 1, 2, 3),
produto = c("Celular", "Notebook", "Tablet", "Smartwatch",
"Fone de Ouvido", "Teclado", "Mouse"),
valor_compra = c(1500, 2500, 800, 300, 100, 80, 50)
)
tidyr
O pacote tidyr
dispõe de funções bastante úteis para organizar os dados no formato necessário para a análise.
Existem dois tipos de formatação dos dados:
As principais funções para transformar os dados para formato long ou wide são:
pivot_longer()
: empilha o banco de dados, deixando no formato longo (long).pivot_wider()
: transforma o banco para um formato expandido (wide).pivot_longer()
pivot_longer()
: empilha o banco de dados, deixando no formato longo.pivot_longer()
Neste exemplo, vamos criar um tibble
:
pivot_longer()
Utilizando a função pivot_longer()
dados_uf_long <- dados_uf |>
pivot_longer(
cols = `2017`:`2019`,
names_to = "ano",
values_to = "valor"
)
dados_uf_long
## # A tibble: 9 × 3
## uf ano valor
## <chr> <chr> <dbl>
## 1 RJ 2017 23
## 2 RJ 2018 20
## 3 RJ 2019 28
## 4 SP 2017 45
## 5 SP 2018 38
## 6 SP 2019 36
## 7 PB 2017 19
## 8 PB 2018 17
## 9 PB 2019 20
Tal formato é bastante utilizado para análises de unidades ao longo do tempo (por exemplo, em análises de dados de séries temporais ou dados em painel)
Altere para long o formato do banco com informações do peso (em gramas) de recém nascidos, transformando apenas as variáveis contendo informações do peso, ordenados em ordem alfabética dos nomes:
peso_recem_nascido <- tibble(
nome = c("João", "Maria", "José", "Ana"),
sobrenome = c("Oliveira", "Duarte", "Silveira", "Cavalcante"),
sexo = c("M", "F", "M", "F"),
mes_0 = c(4300, 5240, 5180, 5450),
mes_1 = c(5300, NA, 6607, 6900),
mes_2 = c(4560, 6301, NA, 8765),
mes_3 = c(5003, NA, 6015, 6399)
)
peso_recem_nascido
## # A tibble: 4 × 7
## nome sobrenome sexo mes_0 mes_1 mes_2 mes_3
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 João Oliveira M 4300 5300 4560 5003
## 2 Maria Duarte F 5240 NA 6301 NA
## 3 José Silveira M 5180 6607 NA 6015
## 4 Ana Cavalcante F 5450 6900 8765 6399
05:00
Neste exercício, retomaremos ao exemplo dos dados históricos do Índice Bovespa (Ibovespa) disponíveis no site da B3 http://www.b3.com.br/pt_br/market-data-e-indices/indices/indices-amplos/indice-ibovespa-ibovespa-estatisticas-historicas.htm
10:00
pivot_wider()
A função pivot_wider()
transforma o banco para um formato expandido (wide)
pivot_wider()
Pra transformar do formato long para wide:
population
inseridos no pacote tidyr
através de tidyr::population
.prefix
par adicionar ano_
antes do nome de cada coluna pivoteada.05:00
Análise de Dados e Documentos Dinâmicos