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(
      massa_corporal < 3000 ~ "Pequeno",
      massa_corporal >= 3000 & massa_corporal < 5000 ~ "Médio",
      massa_corporal >= 5000 ~ "Grande"
    )
  ) |>
  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 ser Pinguim-de-barbicha e também deve ter a massa_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 os NA 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 do summarise(), para que possamos receber os dados do summarise() 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
dados_2014 <- questionario |>
  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