GET00130 - Métodos Computacionais para Estatística II
Conteúdo da aula
- Combinando bases de dados;
- Recodificando variáveis.
1 - Combinando bases de dados
Muitas vezes ao trabalharmos com dados, precisamos combinar fontes de dados (arquivos distintos) em uma única fonte para realizarmos nossas análises.
O pacote dplyr possui um conjunto de funções que nos auxiliam a combinar bases do nosso interesse. Trata-se da família de funções join.
Para discutirmos essas funções, serão criados tibbles bem pequenos, para visualizarmos o que cada uma das funções da família join faz. Qualquer dúvida, não deixe de acessar o help destas funções.
Os objetos d1, d2 e d3 contém informações sobre alguns indivíduos. Em cada base existe uma variável que identifica de forma única cada indivíduo, por exemplo, ID nas bases d1 e d2 e COD_ID na base d3.
# carregando pacote
library(tidyverse)
# criando a base d1 (informações gerais, incluindo código, sexo, idade e se o indivíduo é casado)
d1 <- tibble(ID = c(1010, 2010, 3010, 4010, 5010, 3040, 2020, 1030, 3021,9087,2432,3456),
Sexo = c('M', 'F', 'F', 'M', 'M','M', 'F', 'F', 'M', 'M','F', 'F'),
Idade = c(20, 21, 30, 28, 21, 30, 31, 10, 18, 21,35,65),
Casado=c(0,0,1,1,1,0,0,0,0,0,1,1))
d1# A tibble: 12 x 4
ID Sexo Idade Casado
<dbl> <chr> <dbl> <dbl>
1 1010 M 20 0
2 2010 F 21 0
3 3010 F 30 1
4 4010 M 28 1
5 5010 M 21 1
6 3040 M 30 0
7 2020 F 31 0
8 1030 F 10 0
9 3021 M 18 0
10 9087 M 21 0
11 2432 F 35 1
12 3456 F 65 1
#Criando a base d2 (informações extras somente para os casados)
d2 <- tibble(ID = c(3010, 4010, 5010,2432,3456),
Tempo_casado = c(8, 2, 1, 10, 32),
Primeiro_casamento = c(0, 1, 1, 0, 0),
Sexo_companheiro=c('F','F','F','M','M'))
d2# A tibble: 5 x 4
ID Tempo_casado Primeiro_casamento Sexo_companheiro
<dbl> <dbl> <dbl> <chr>
1 3010 8 0 F
2 4010 2 1 F
3 5010 1 1 F
4 2432 10 0 M
5 3456 32 0 M
#Criando a base d3, identica a d2, mas modificando o nome da variável que tem o código do indivíduo
d3 <- tibble(COD_ID = c(3010, 4010, 5010,2432,3456),
Tempo_casado = c(8, 2, 1, 10, 32),
Primeiro_casamento = c(0, 1, 1, 0, 0),
Sexo_companheiro=c('F','F','F','M','M'))
d3# A tibble: 5 x 4
COD_ID Tempo_casado Primeiro_casamento Sexo_companheiro
<dbl> <dbl> <dbl> <chr>
1 3010 8 0 F
2 4010 2 1 F
3 5010 1 1 F
4 2432 10 0 M
5 3456 32 0 M
Como combinar as bases d1 e d2 para termos somente os indivíduos comuns nas duas bases e todas as variáveis em um único objeto???
Nossa resposta para esses questionamentos sempre será: TIDYVERSE neles.
A função que será usada para alcançarmos o objetivo desejado é a função inner_join. O objetivo da função é retornar um objeto com todas as linhas da base x que tem uma correspondência com a base y (correspondência que será avaliada por meio de uma chave), e todas as colunas de x e y. A animação abaixo exemplifica a função (todas as animações foram retiradas do material de Garrick Aden‑Buie).
Principais argumentos da função inner_join (e das demais funções da família join):
- x - um dos tibbles a serem fundidos (o tibble da esquerda);
- y - um dos tibbles a serem fundidos (o tibble da direita);
- by - a variável (as variáveis) que utilizaremos para juntar os tibbles.
# Função inner_join: Combina as duas bases incluindo todas as variáveis
# de ambas as bases e todas as linhas comuns as duas bases
merge1 = inner_join(x = d1,
y = d2,
by = "ID")
merge1# A tibble: 5 x 7
ID Sexo Idade Casado Tempo_casado Primeiro_casamento Sexo_companheiro
<dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
1 3010 F 30 1 8 0 F
2 4010 M 28 1 2 1 F
3 5010 M 21 1 1 1 F
4 2432 F 35 1 10 0 M
5 3456 F 65 1 32 0 M
Podemos notar que o comando retorna somente os indivíduos casados (presentes nas duas bases) e as variáveis de ambas as bases.
Já a função left_join tem por objetivo retornar um objeto com todas as linhas da base x e todas as colunas de x e y. Linhas em x que não possuem correspondência em y terão valores NA nas novas colunas criadas.
# Função left_join: Combina as duas bases incluindo todas as variáveis
# de ambas as bases e todas as linhas da base a esquerda
merge2 = left_join(x = d1,
y = d3,
by = c("ID"="COD_ID"))
merge2# A tibble: 12 x 7
ID Sexo Idade Casado Tempo_casado Primeiro_casamento Sexo_companheiro
<dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
1 1010 M 20 0 NA NA <NA>
2 2010 F 21 0 NA NA <NA>
3 3010 F 30 1 8 0 F
4 4010 M 28 1 2 1 F
5 5010 M 21 1 1 1 F
6 3040 M 30 0 NA NA <NA>
7 2020 F 31 0 NA NA <NA>
8 1030 F 10 0 NA NA <NA>
9 3021 M 18 0 NA NA <NA>
10 9087 M 21 0 NA NA <NA>
11 2432 F 35 1 10 0 M
12 3456 F 65 1 32 0 M
Podemos notar que o comando retorna todos os indivíduos da base a esquerda (a base d1) e as variáveis de ambas as bases. Como a base d3 não possui as informações para os casados, as variáveis referentes a base d3 são preenchidas com NA para os solteiros. Outro ponto que precisamos mencionar é que a variável usada para fundir as bases possuem nomes diferentes nas suas bases, logo, foi preciso informar isso no argumento by, passamos primeiro o nome da variável na base a esquerda e depois o nome na base a direita.
A seguir criamos outros dois tibbles contendo informações sobre municípios em dois anos (2000 e 2010). O segundo arquivo criado possui dados somente para alguns municípios que são capitais. Desejamos unir as duas bases, de modo que o resultado seja uma base com todos os munícipios e todas as variáveis.
#Criando a base d4 (informações gerais sobre alguns municípios)
d4 <- tibble(IDmun = c(1010, 1010, 2010, 2010, 3010, 3010, 4010, 4010, 5010,5010,6010,6010),
ano = c(2000,2010,2000,2010,2000,2010,2000,2010,2000,2010,2000,2010),
Capital = c('S', 'S', 'N', 'N', 'S','S', 'N', 'N', 'S', 'S','N', 'N'),
popjovem = c(1228, 2221, 1230, 2228, 1225, 2225, 731, 1225, 828, 3421,1235,5429))
d4# A tibble: 12 × 4
IDmun ano Capital popjovem
<dbl> <dbl> <chr> <dbl>
1 1010 2000 S 1228
2 1010 2010 S 2221
3 2010 2000 N 1230
4 2010 2010 N 2228
5 3010 2000 S 1225
6 3010 2010 S 2225
7 4010 2000 N 731
8 4010 2010 N 1225
9 5010 2000 S 828
10 5010 2010 S 3421
11 6010 2000 N 1235
12 6010 2010 N 5429
#Criando a base d5 (informações extras somente para as capitais)
d5 <- tibble(ID = c(9010, 9010, 1010, 1010, 5010, 5010),
ano = c(2000,2010,2000,2010,2000,2010),
IDH = c(0.65, 0.7, 0.55, 0.72, 0.7,0.78),
Capital=c('S','S','S','S','S','S'))
d5# A tibble: 6 × 4
ID ano IDH Capital
<dbl> <dbl> <dbl> <chr>
1 9010 2000 0.65 S
2 9010 2010 0.7 S
3 1010 2000 0.55 S
4 1010 2010 0.72 S
5 5010 2000 0.7 S
6 5010 2010 0.78 S
A função full_join tem por objetivo retornar um objeto com todas as linhas e todas as colunas das bases x e y. Quando não houver correspondência ns duas bases, serão retornado valores NA.
# Combinando as duas bases
merge3 = full_join(x = d4,
y = d5,
by = c("IDmun" = "ID"))
merge3# A tibble: 18 × 7
IDmun ano.x Capital.x popjovem ano.y IDH Capital.y
<dbl> <dbl> <chr> <dbl> <dbl> <dbl> <chr>
1 1010 2000 S 1228 2000 0.55 S
2 1010 2000 S 1228 2010 0.72 S
3 1010 2010 S 2221 2000 0.55 S
4 1010 2010 S 2221 2010 0.72 S
5 2010 2000 N 1230 NA NA <NA>
6 2010 2010 N 2228 NA NA <NA>
7 3010 2000 S 1225 NA NA <NA>
8 3010 2010 S 2225 NA NA <NA>
9 4010 2000 N 731 NA NA <NA>
10 4010 2010 N 1225 NA NA <NA>
11 5010 2000 S 828 2000 0.7 S
12 5010 2000 S 828 2010 0.78 S
13 5010 2010 S 3421 2000 0.7 S
14 5010 2010 S 3421 2010 0.78 S
15 6010 2000 N 1235 NA NA <NA>
16 6010 2010 N 5429 NA NA <NA>
17 9010 NA <NA> NA 2000 0.65 S
18 9010 NA <NA> NA 2010 0.7 S
Claramente não atingimos o nosso objetivo com o código acima. O resultado está ERRADO!!! Uma vez que cada município está aparecendo 4 vezes na base e só temos informações referentes a 2 anos destes municípios.
A chave usada, não identifica de forma única cada linha da base, uma vez que os municípios se repetem, para identificar de forma única, precisaremos usar uma chave secundária (o ano). A função usada está correta.
# Fundindo bases usando mais de uma chave
# Função full_join: Combina as duas bases incluindo todas as variáveis
# de ambas as bases e todas as linhas de todas a s bases
merge3 = full_join(x = d4,
y = d5,
by = c("IDmun" = "ID", "ano"))
merge3# A tibble: 14 × 6
IDmun ano Capital.x popjovem IDH Capital.y
<dbl> <dbl> <chr> <dbl> <dbl> <chr>
1 1010 2000 S 1228 0.55 S
2 1010 2010 S 2221 0.72 S
3 2010 2000 N 1230 NA <NA>
4 2010 2010 N 2228 NA <NA>
5 3010 2000 S 1225 NA <NA>
6 3010 2010 S 2225 NA <NA>
7 4010 2000 N 731 NA <NA>
8 4010 2010 N 1225 NA <NA>
9 5010 2000 S 828 0.7 S
10 5010 2010 S 3421 0.78 S
11 6010 2000 N 1235 NA <NA>
12 6010 2010 N 5429 NA <NA>
13 9010 2000 <NA> NA 0.65 S
14 9010 2010 <NA> NA 0.7 S
Podemos ver que a modificação realizada, isto é, a inclusão da segunda chave, permite que a junção das base seja feita de forma correta. Temos como resultado final uma base com todos os municípios, incluindo os comuns as duas bases, os que só se encontravam em d4 e os que só se encontravam em d5 e as variáveis das duas bases.
Podemos perceber também que em d4 e d5 possuem variáveis com o mesmo nome. O objeto resultante possui as duas variáveis Capital, o sufixo .x indica que a variável é proveniente da base a esquerda e o .y indica que a variável proveniente da base a direita.
No argumento by, como o nome da variável código estava diferente nas duas bases foi preciso informar o nome em cada base, para a variável ano já não foi necessário.
Ainda podemos citar as funções:
anti_join: retorna as linhas de x sem correspondentes em y, mantendo apenas as colunas de x,right_join: retorna todas as linhas de y, e todas as colunas de x e y.
2 - Combinando dados verticalmente
Os objetos v1, v2 e v3 contém informações sobre alguns indivíduos. Todas as base contém exatamente as mesmas variáveis.
#Criando a base d1
v1 <- tibble(ID = c(1010, 2010, 3010, 4010, 5010),
W = c('a', 'b', 'a', 'b', 'e'),
X = c(1, 1, 0, 0, 1),
Y = c(3,6,3,5,7))
v1# A tibble: 5 × 4
ID W X Y
<dbl> <chr> <dbl> <dbl>
1 1010 a 1 3
2 2010 b 1 6
3 3010 a 0 3
4 4010 b 0 5
5 5010 e 1 7
#Criando a base d2
v2 <- tibble(ID = c(1010, 2010, 5010),
W = c('a', 'b', 'e'),
X = c(1, 1, 1),
Y = c(3,6,7))
v2# A tibble: 3 × 4
ID W X Y
<dbl> <chr> <dbl> <dbl>
1 1010 a 1 3
2 2010 b 1 6
3 5010 e 1 7
#Criando a base d3
v3 <- tibble(ID = c(4010, 2011, 1017),
W = c('b', 'e', "a"),
X = c(0,0,1),
Y = c(5,5,4))
v3# A tibble: 3 × 4
ID W X Y
<dbl> <chr> <dbl> <dbl>
1 4010 b 0 5
2 2011 e 0 5
3 1017 a 1 4
Suponha que desejamos criar um objeto somente com as linhas comuns as duas bases v1 e v2. Podemos realizar esta tarefa usando a função intersect.
Principais argumentos da função intersect
- x - um dos tibbles a serem operacionalizados;
- y - um dos tibbles a serem operacionalizados.
#Criando uma base com as linhas comus as duas bases
intersect(x = v1,
y = v2)# A tibble: 3 × 4
ID W X Y
<dbl> <chr> <dbl> <dbl>
1 1010 a 1 3
2 2010 b 1 6
3 5010 e 1 7
O resultado retorna todas as linhas comuns aos objetos v1 e v2.
Já a função setdiff retorna os elementos de uma base, retirando as interseções que a mesma possui com uma outra base.
Principais argumentos da função setdiff
- x - um dos tibbles a serem operacionalizados;
- y - um dos tibbles a serem operacionalizados.
#Criando uma base com as linhas distintas nas duas bases
setdiff(x = v1,
y = v3)# A tibble: 4 × 4
ID W X Y
<dbl> <chr> <dbl> <dbl>
1 1010 a 1 3
2 2010 b 1 6
3 3010 a 0 3
4 5010 e 1 7
O resultado retorna todas as linhas do objeto v1, retirando as linhas comuns entre os objetos v1 e v3.
Suponha que desejamos criar um objeto com todas as linhas das bases v1 e v3. Podemos realizar esta tarefa usando a função union.
Principais argumentos da função union
- x - um dos tibbles a serem operacionalizados;
- y - um dos tibbles a serem operacionalizados.
#Criando uma base unindo todas as linhas das duas bases
union(x = v1,
y = v3)# A tibble: 7 × 4
ID W X Y
<dbl> <chr> <dbl> <dbl>
1 1010 a 1 3
2 2010 b 1 6
3 3010 a 0 3
4 4010 b 0 5
5 5010 e 1 7
6 2011 e 0 5
7 1017 a 1 4
O resultado retorna todas as linhas dos objetos v1 e v3. Perceba que o objeto v1 possui 5 linhas e o objeto v3 possui 3 linhas, entretanto a ação resultante retorna 7 linhas (e não 8), isto acontece porque existe 1 indivíduo comum as duas bases. A função union elimina linhas repetidas.
A função bind_rows tem o objetivo de empilhar duas bases de dados.
#Empilhando duas bases, uma em cima da outra
bind_rows(v1,v3)# A tibble: 8 × 4
ID W X Y
<dbl> <chr> <dbl> <dbl>
1 1010 a 1 3
2 2010 b 1 6
3 3010 a 0 3
4 4010 b 0 5
5 5010 e 1 7
6 4010 b 0 5
7 2011 e 0 5
8 1017 a 1 4
Percebemos que o resultado é diferente da função union, uma vez que a função bind_rows somente empilha sem checar se existem linhas repetidas. O resultado final possui 8 linhas, incluindo duas vezes a linha referente ao indivíduo 4010.
#Criando a base d4
v4 <- tibble(ID = c(4010, 2011, 1017),
idade = c(10,20,32),
Sexo = c(1,0,1))
v4# A tibble: 3 × 3
ID idade Sexo
<dbl> <dbl> <dbl>
1 4010 10 1
2 2011 20 0
3 1017 32 1
A função bind_cols tem o objetivo de acoplar duas bases de dados, uma ao lado da outra. Naturalmente para fazer o uso desta função, as bases precisam ter a mesma ordenação.
#Acoplar duas bases, uma ao lado da outra
bind_cols(v3,v4)New names:
* ID -> ID...1
* ID -> ID...5
# A tibble: 3 × 7
ID...1 W X Y ID...5 idade Sexo
<dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 4010 b 0 5 4010 10 1
2 2011 e 0 5 2011 20 0
3 1017 a 1 4 1017 32 1
Percebemos que o resultado é diferente da função union, uma vez que a função bind_rows somente empilha sem checar se existem linhas repetidas. O resultado final possui 8 linhas, incluindo duas vezes a linha referente ao indivíduo 4010.
3 - Recodificando variáveis
Outra tarefa recorrente para quem trabalha com dados é a recodificação de variáeis. Abaixo é apresentada a função do pacote dplyr para realizar tal tarefa.
Atividade: Importe o arquivo Populacao por micro sexo e idade.csv e guarde em um objeto chamado base_Pop. Este objeto contem o total de habitantes para combinações de categorias de sexo e idade por microrregiões.
#Visualizando o objeto
base_Pop# A tibble: 2,232 × 4
Microrregiao SEXO IDADE.CAT tot.pop
<dbl> <dbl> <dbl> <dbl>
1 11001 0 0 153264
2 11001 0 1 110853
3 11001 1 0 159442
4 11001 1 1 116761
5 11002 0 0 20878
6 11002 0 1 13927
7 11002 1 0 21756
8 11002 1 1 14808
9 11003 0 0 47872
10 11003 0 1 35058
# … with 2,222 more rows
Atividade: Crie um objeto chamado pop_Micro que contem o total de habitantes por microrregião (populacao).
#Visualizando o objeto
pop_Micro# A tibble: 558 × 2
Microrregiao populacao
<dbl> <dbl>
1 11001 540320
2 11002 71369
3 11003 171150
4 11004 295466
5 11005 70184
6 11006 228212
7 11007 132677
8 11008 53031
9 12001 131505
10 12002 74579
# … with 548 more rows
Agora, vamos criar duas variáveis na base de dados em função do total populacional. A primeira variável será chamada de pop.cat1 vai categorizar a população em Pequena (< 350.000) e Grande (caso contrário). A segunda variável será chamada de pop.cat2 vai categorizar a população em três faixas: Pequena (menor ou igual a 100.000), Grande (acima de 500.000) e Intermediária (caso contrário).
Iremos utilizadar funções já vistas como a mutate e novas funções como a if_else e cut.
Principais argumentos da função cut
- x - a variável que será categorizada;
- breaks - um vetor com os limites inferiores e superiores das categorias;
- labels - os rótulos associadas as categorias formadas pelos breaks.
#Criando a variável pop.cat1
pop_Micro = pop_Micro |>
mutate(pop.cat1 = if_else(populacao < 350000, "Pequena", "Grande"),
pop.cat2 = cut(x = populacao,
breaks = c(0,100000,500000,Inf),
labels = c("Pequena","Intermediária","Grande")))
#Visualizando o objeto
pop_Micro# A tibble: 558 × 4
Microrregiao populacao pop.cat1 pop.cat2
<dbl> <dbl> <chr> <fct>
1 11001 540320 Grande Grande
2 11002 71369 Pequena Pequena
3 11003 171150 Pequena Intermediária
4 11004 295466 Pequena Intermediária
5 11005 70184 Pequena Pequena
6 11006 228212 Pequena Intermediária
7 11007 132677 Pequena Intermediária
8 11008 53031 Pequena Pequena
9 12001 131505 Pequena Intermediária
10 12002 74579 Pequena Pequena
# … with 548 more rows
Suponha que desejamos recodificar a categoria Intermediária para Mediana e a categoria Grande para Grandes centros da variável pop.cat2. Para realizar tal tarefa iremos utilizar a função recode.
Principais argumentos da função recode
- .x - a variável que terá valores (categorias) recodificadas.
#Criando a variável pop.cat2
pop_Micro = pop_Micro |>
mutate(pop.cat2 = recode(.x = pop.cat2, "Intermediária" = "Mediana", "Grande" = "Grande centros"))
#Visualizando o objeto
pop_Micro# A tibble: 558 × 4
Microrregiao populacao pop.cat1 pop.cat2
<dbl> <dbl> <chr> <fct>
1 11001 540320 Grande Grande centros
2 11002 71369 Pequena Pequena
3 11003 171150 Pequena Mediana
4 11004 295466 Pequena Mediana
5 11005 70184 Pequena Pequena
6 11006 228212 Pequena Mediana
7 11007 132677 Pequena Mediana
8 11008 53031 Pequena Pequena
9 12001 131505 Pequena Mediana
10 12002 74579 Pequena Pequena
# … with 548 more rows
Para realizar a recodificação criamos uma variável com o mesmo nome da variável original, ou seja, substituímos a variável existente por uma na qual a categoria Intermediária foi recodificada para Mediana. Note que os os valores que serão recodificados (sejam numéricos ou strings) devem ser informados antes da igualdade entre aspas.
Suponha que desejamos recodificar a categoria Pequena para Muito pequena da variável pop.cat1.
#Criando a variável pop.cat1
pop_Micro = pop_Micro |>
mutate(pop.cat1 = recode(.x = pop.cat1, "Pequena" = "Muito pequena"))
#Visualizando o objeto
pop_Micro# A tibble: 558 × 4
Microrregiao populacao pop.cat1 pop.cat2
<dbl> <dbl> <chr> <fct>
1 11001 540320 Grande Grande centros
2 11002 71369 Muito pequena Pequena
3 11003 171150 Muito pequena Mediana
4 11004 295466 Muito pequena Mediana
5 11005 70184 Muito pequena Pequena
6 11006 228212 Muito pequena Mediana
7 11007 132677 Muito pequena Mediana
8 11008 53031 Muito pequena Pequena
9 12001 131505 Muito pequena Mediana
10 12002 74579 Muito pequena Pequena
# … with 548 more rows
Para realizar a recodificação criamos uma variável com o mesmo nome da variável original no objeto, ou seja, substituímos a variável existente pop.cat1 por outra variável pop.cat1 na qual não existe a categoria Intermediária e sim a categoria Mediana.
Vale ressaltar, que as duas recodificações realizadas por meio da função recode criou variáveis com a mesma classe da variável que foi recodificada, isto é, a nova variável pop.cat1 é chr (antes e depois da operação de recodificação) e a variável pop.cat2 é fct (antes e depois da operação de recodificação).
Se desejássemos recodificar uma variável e que a nova variável fosse um fator, independente da sua classe, devemos usar a funçao recode_factor.
#Criando a variável pop.cat1_f
pop_Micro = pop_Micro |>
mutate(pop.cat1_f = recode_factor(.x = pop.cat1, "Pequena" = "Muito pequena"))
#Visualizando o objeto
pop_Micro# A tibble: 558 × 5
Microrregiao populacao pop.cat1 pop.cat2 pop.cat1_f
<dbl> <dbl> <chr> <fct> <fct>
1 11001 540320 Grande Grande centros Grande
2 11002 71369 Muito pequena Pequena Muito pequena
3 11003 171150 Muito pequena Mediana Muito pequena
4 11004 295466 Muito pequena Mediana Muito pequena
5 11005 70184 Muito pequena Pequena Muito pequena
6 11006 228212 Muito pequena Mediana Muito pequena
7 11007 132677 Muito pequena Mediana Muito pequena
8 11008 53031 Muito pequena Pequena Muito pequena
9 12001 131505 Muito pequena Mediana Muito pequena
10 12002 74579 Muito pequena Pequena Muito pequena
# … with 548 more rows