Gabarito da Aula 2: Manipulação de dados
1. Escolha uma das bases de dados do pacote dados
e utilize ao menos uma vez as funções: select()
, mutate()
, filter()
, arrange()
, summarise()
e group_by()
(as bases disponíveis podem ser acessadas no site de referência do pacote).
O exercício solicita que nós escolhamos alguma base de dados do pacote dados
para usar para na tarefa. Portanto, farei uso de uma base de dados chamada pinguins
que é uma das incluídas no pacote dados
.
Essa base de dados inclui espécies de pinguins e ilhas do Arquipélago Palmer, medidas de cada espécie (comprimento da nadadeira, massa corporal e dimensões do bico), sexo de cada pinguim e ano da documentação.
Segue abaixo a base de dados original:
1.1. Função select()
A função select()
pode ser usada para selecionar colunas específicas da base de dados, ou até mesmo para remover colunas indesejadas.
# Solução 1 para `select()`
library(dados)
library(dplyr)
|>
pinguins select(ano, ilha, comprimento_bico)
- 1
- Carregar pacotes.
- 2
-
Especificar que usarei os dados
pinguins
. - 3
- Selecionar apenas as colunas especificadas.
# A tibble: 344 × 3
ano ilha comprimento_bico
<int> <fct> <dbl>
1 2007 Torgersen 39.1
2 2007 Torgersen 39.5
3 2007 Torgersen 40.3
4 2007 Torgersen NA
5 2007 Torgersen 36.7
6 2007 Torgersen 39.3
7 2007 Torgersen 38.9
8 2007 Torgersen 39.2
9 2007 Torgersen 34.1
10 2007 Torgersen 42
# ℹ 334 more rows
# Solução 2 para `select()`
|>
pinguins select(-comprimento_nadadeira,
-profundidade_bico,-ilha,
-massa_corporal)
- 1
-
Remover as colunas adicionando um
-
antes do nome da variável.
# A tibble: 344 × 4
especie comprimento_bico sexo ano
<fct> <dbl> <fct> <int>
1 Pinguim-de-adélia 39.1 macho 2007
2 Pinguim-de-adélia 39.5 fêmea 2007
3 Pinguim-de-adélia 40.3 fêmea 2007
4 Pinguim-de-adélia NA <NA> 2007
5 Pinguim-de-adélia 36.7 fêmea 2007
6 Pinguim-de-adélia 39.3 macho 2007
7 Pinguim-de-adélia 38.9 fêmea 2007
8 Pinguim-de-adélia 39.2 macho 2007
9 Pinguim-de-adélia 34.1 <NA> 2007
10 Pinguim-de-adélia 42 <NA> 2007
# ℹ 334 more rows
1.2. Função mutate()
Modificando uma variável
Como comentado em aula, uma das funcionalidades da função mutate()
é a de modificar uma variável já existente na base de dados. Isto é feito utilizando o mutate e atribuindo como nome da variável, o mesmo nome já usado. Dessa forma, estaremos reatribuindo a variável (coluna) com os novos valores, ou seja, modificando-a.
Vamos supor que desejamos modificar a variável da massa_corporal
, que está originalmente em gramas, para quilogramas. Podemos fazer o seguinte:
# Solução 1 para `mutate()`
|>
pinguins mutate(massa_corporal = massa_corporal / 1000) |>
relocate(massa_corporal, .before = everything())
- 1
- Transformando variável da massa corporal para unidade kg.
- 2
-
Posicionando coluna da
massa_corporal
antes de todas as outras.
# A tibble: 344 × 8
massa_corporal especie ilha comprimento_bico profundidade_bico
<dbl> <fct> <fct> <dbl> <dbl>
1 3.75 Pinguim-de-adélia Torgersen 39.1 18.7
2 3.8 Pinguim-de-adélia Torgersen 39.5 17.4
3 3.25 Pinguim-de-adélia Torgersen 40.3 18
4 NA Pinguim-de-adélia Torgersen NA NA
5 3.45 Pinguim-de-adélia Torgersen 36.7 19.3
6 3.65 Pinguim-de-adélia Torgersen 39.3 20.6
7 3.62 Pinguim-de-adélia Torgersen 38.9 17.8
8 4.68 Pinguim-de-adélia Torgersen 39.2 19.6
9 3.48 Pinguim-de-adélia Torgersen 34.1 18.1
10 4.25 Pinguim-de-adélia Torgersen 42 20.2
# ℹ 334 more rows
# ℹ 3 more variables: comprimento_nadadeira <int>, sexo <fct>, ano <int>
A função relocate()
do dplyr
foi usada apenas para colocar a variável massa_corporal
(então modificada) como a primeira variável (coluna) da base para que possamos ver os novos valores atribuídos a ela.
Criando uma nova variável numérica
Em aula, também vimos como poderíamos criar uma nova variável numérica usando o mutate()
. Segue uma possível solução abaixo onde calculamos a razão do bico, ou seja, comprimento do bico dividido pela profundidade do bico:
# Solução 2 para `mutate()`
|>
pinguins mutate(razao_bico = comprimento_bico / profundidade_bico) |>
relocate(razao_bico, .before = everything())
# A tibble: 344 × 9
razao_bico especie ilha comprimento_bico profundidade_bico
<dbl> <fct> <fct> <dbl> <dbl>
1 2.09 Pinguim-de-adélia Torgersen 39.1 18.7
2 2.27 Pinguim-de-adélia Torgersen 39.5 17.4
3 2.24 Pinguim-de-adélia Torgersen 40.3 18
4 NA Pinguim-de-adélia Torgersen NA NA
5 1.90 Pinguim-de-adélia Torgersen 36.7 19.3
6 1.91 Pinguim-de-adélia Torgersen 39.3 20.6
7 2.19 Pinguim-de-adélia Torgersen 38.9 17.8
8 2 Pinguim-de-adélia Torgersen 39.2 19.6
9 1.88 Pinguim-de-adélia Torgersen 34.1 18.1
10 2.08 Pinguim-de-adélia Torgersen 42 20.2
# ℹ 334 more rows
# ℹ 4 more variables: comprimento_nadadeira <int>, massa_corporal <int>,
# sexo <fct>, ano <int>
Criando uma variável categórica
Outra tarefa importante que podemos estar realizando com mutate()
, mas que não foi comentado diretamente em aula, é a criação de variáveis categóricas. E isso pode ser feito com o auxílio de uma outra função do pacote dplyr
chamada case_when()
. Essa função nos ajuda a testar várias expressões lógicas e atribuir valores à nossa nova variável a partir das condições. Segue exemplo onde criamos categorias para a massa corporal dos pinguins, onde até 3.000g trata-se de um pinguim pequeno, 3.000g a 5.000g, um médio e mais de 5.000g, grande.
# Solução 3 para `mutate()`
|>
pinguins mutate(
categoria_massa = case_when(
< 3000 ~ "Pequeno",
massa_corporal >= 3000 & massa_corporal < 5000 ~ "Médio",
massa_corporal >= 5000 ~ "Grande"
massa_corporal
)|>
) relocate(c(categoria_massa, massa_corporal),
.before = everything())
- 1
-
Inicia a função
case_when()
. - 2
-
Caso
massa_corporal
seja menor que 3 mil gramas, é um penguim pequeno. - 3
-
Caso
massa_corporal
seja maior ou igual que 3 mil gramas, e também menor que 5 mil gramas, é um penguim médio. - 4
-
Caso
massa_corporal
seja maior ou igual que 5 mil gramas, é um penguim grande. - 5
-
Finalizar função
mutate()
.
# A tibble: 344 × 9
categoria_massa massa_corporal especie ilha comprimento_bico
<chr> <int> <fct> <fct> <dbl>
1 Médio 3750 Pinguim-de-adélia Torgersen 39.1
2 Médio 3800 Pinguim-de-adélia Torgersen 39.5
3 Médio 3250 Pinguim-de-adélia Torgersen 40.3
4 <NA> NA Pinguim-de-adélia Torgersen NA
5 Médio 3450 Pinguim-de-adélia Torgersen 36.7
6 Médio 3650 Pinguim-de-adélia Torgersen 39.3
7 Médio 3625 Pinguim-de-adélia Torgersen 38.9
8 Médio 4675 Pinguim-de-adélia Torgersen 39.2
9 Médio 3475 Pinguim-de-adélia Torgersen 34.1
10 Médio 4250 Pinguim-de-adélia Torgersen 42
# ℹ 334 more rows
# ℹ 4 more variables: profundidade_bico <dbl>, comprimento_nadadeira <int>,
# sexo <fct>, ano <int>
1.3. Função filter()
Na solução abaixo, filtramos a base de dados para manter apenas os pinguins-de-barbicha que possuem massa corporal menor que 3.500g.
# Solução para `filter()`
|>
pinguins filter(especie == "Pinguim-de-barbicha" & massa_corporal > 3500)
- 1
-
Notem que o
&
indica que todas as expressões lógicas devem ser respeitadas. O pinguim deve serPinguim-de-barbicha
e também deve ter amassa_corporal
maior que 3.500 gramas.
# A tibble: 49 × 8
especie ilha comprimento_bico profundidade_bico comprimento_nadadeira
<fct> <fct> <dbl> <dbl> <int>
1 Pinguim-de-ba… Dream 50 19.5 196
2 Pinguim-de-ba… Dream 51.3 19.2 193
3 Pinguim-de-ba… Dream 45.4 18.7 188
4 Pinguim-de-ba… Dream 52.7 19.8 197
5 Pinguim-de-ba… Dream 45.2 17.8 198
6 Pinguim-de-ba… Dream 51.3 18.2 197
7 Pinguim-de-ba… Dream 46 18.9 195
8 Pinguim-de-ba… Dream 51.3 19.9 198
9 Pinguim-de-ba… Dream 46.6 17.8 193
10 Pinguim-de-ba… Dream 51.7 20.3 194
# ℹ 39 more rows
# ℹ 3 more variables: massa_corporal <int>, sexo <fct>, ano <int>
1.4. Função arrange()
No exemplo abaixo, ordenamos a base de forma decrescente pelo comprimento_bico
dos pinguins, ou seja, os pinguins com bicos mais compridos estarão mais para cima na base de dados.
# Solução para `arrange()`
|>
pinguins arrange(desc(comprimento_bico))
- 1
- Percebam que os pinguins com os maiores bicos estão ao topo da tabela retornada pelo R.
# A tibble: 344 × 8
especie ilha comprimento_bico profundidade_bico comprimento_nadadeira
<fct> <fct> <dbl> <dbl> <int>
1 Pinguim-gentoo Bisc… 59.6 17 230
2 Pinguim-de-ba… Dream 58 17.8 181
3 Pinguim-gentoo Bisc… 55.9 17 228
4 Pinguim-de-ba… Dream 55.8 19.8 207
5 Pinguim-gentoo Bisc… 55.1 16 230
6 Pinguim-gentoo Bisc… 54.3 15.7 231
7 Pinguim-de-ba… Dream 54.2 20.8 201
8 Pinguim-de-ba… Dream 53.5 19.9 205
9 Pinguim-gentoo Bisc… 53.4 15.8 219
10 Pinguim-de-ba… Dream 52.8 20 205
# ℹ 334 more rows
# ℹ 3 more variables: massa_corporal <int>, sexo <fct>, ano <int>
1.5. Função summarise()
Nesta solução, calculo a média e o desvio padrão da massa corporal dos pinguins-gentoo da base de dados (notem que faço um filter()
antes do summarise()
).
# Solução para `summarise()`
|>
pinguins filter(especie == "Pinguim-gentoo") |>
summarise(
media_massa = mean(massa_corporal, na.rm = TRUE),
dp_massa = sd(massa_corporal, na.rm = TRUE)
)
- 1
-
Primeiro, os dados foram filtrados para manter apenas os pinguins de espécie
Pinguim-gentoo
. - 2
-
E então calculamos a média e desvio padrão. Notem o uso do argumento
na.rm = TRUE
para ignorar osNA
nos cálculos.
# A tibble: 1 × 2
media_massa dp_massa
<dbl> <dbl>
1 5076. 504.
1.6. Função group_by()
Como vimos em aula, a função group_by()
foi criada para que nós possamos rodar outras funções de forma agrupada (estratificada) baseada em uma variável. Na solução abaixo, calculamos a mediana e a média da massa corporal dos pinguins estratificado pela espécie deles.
# Solução para `group_by()`
|>
pinguins group_by(especie) |>
summarise(
mediana_massa = median(massa_corporal, na.rm = TRUE),
media_massa = mean(massa_corporal, na.rm = TRUE)
)
- 1
-
Percebam que usamos o
group_by()
antes dosummarise()
, para que possamos receber os dados dosummarise()
de forma agrupada.
# A tibble: 3 × 3
especie mediana_massa media_massa
<fct> <dbl> <dbl>
1 Pinguim-de-adélia 3700 3701.
2 Pinguim-de-barbicha 3700 3733.
3 Pinguim-gentoo 5000 5076.
Para fins de curiosidade, exponho também um argumento chamado .by =
da função summarise()
que tem o mesmo propósito da função group_by()
. A solução acima ficaria da seguinte forma com esta adaptação:
|>
pinguins summarise(
mediana_massa = median(massa_corporal, na.rm = TRUE),
media_massa = mean(massa_corporal, na.rm = TRUE),
.by = especie
)
- 1
-
Notem que com o uso deste argumento
.by =
, o resultado é o mesmo.
# A tibble: 3 × 3
especie mediana_massa media_massa
<fct> <dbl> <dbl>
1 Pinguim-de-adélia 3700 3701.
2 Pinguim-gentoo 5000 5076.
3 Pinguim-de-barbicha 3700 3733.
2. Nos dados questionario
do pacote dados
, crie um subconjunto apenas com as observações do ano de 2014 e armazene em um objeto chamado dados_2014
.
Segue solução abaixo:
# Solução para Exercício 2
<- questionario |>
dados_2014 filter(ano == 2014)
dados_2014
- 1
- Primeiro, especificamos o nome do objeto a ser atribuído e quais dados estão sendo trabalhados.
- 2
-
Então, filtramos os dados para manter apenas as observações coletadas no
ano
de 2014. - 3
- Por fim, mostramos o resultado da criação do subconjunto escrevendo o nome do objeto e rodando.
# A tibble: 2,538 × 9
ano estado_civil idade raca renda partido religiao denominacao horas_tv
<int> <fct> <int> <fct> <fct> <fct> <fct> <fct> <int>
1 2014 Divorciado(a) 53 Branca US$ 2… Não fo… Católica Não se apl… NA
2 2014 Casado(a) 26 Branca US$ 2… Não fo… Católica Não se apl… NA
3 2014 Divorciado(a) 59 Branca Não s… Fortem… Protest… Sínodo lut… 4
4 2014 Casado(a) 56 Branca US$ 1… Não fo… Católica Não se apl… 2
5 2014 Casado(a) 74 Branca Não s… Indepe… Católica Não se apl… NA
6 2014 Casado(a) 56 Branca US$ 2… Fortem… Protest… Episcopal 1
7 2014 Casado(a) 63 Branca Se ne… Fortem… Católica Não se apl… 4
8 2014 Casado(a) 34 Branca US$ 2… Não sa… Católica Não se apl… 2
9 2014 Nunca casou 37 Branca Não s… Indepe… Católica Não se apl… NA
10 2014 Casado(a) 30 Outra US$ 2… Indepe… Católica Não se apl… NA
# ℹ 2,528 more rows