Capítulo 16 Manipulação de dados
16.1 Tibbles
Tibbles são uma versão moderna e melhorada dos data frames em R,
introduzida pelo pacote tibble
, que faz parte do tidyverse
— um
conjunto de pacotes desenvolvido para facilitar a ciência de dados em R.
Os tibbles foram projetados para ultrapassar algumas das limitações dos
data frames tradicionais, oferecendo uma estrutura de dados mais robusta
e intuitiva para manipulação e análise de dados.
Diferenças Principais entre Tibble e Data Frame
Os tibbles têm várias vantagens em relação aos data frames,
especialmente em termos de usabilidade e integração com o tidyverse
. A
tabela abaixo resume as principais diferenças:
Característica | Data Frame | Tibble |
---|---|---|
Impressão no Console | Exibe todos os dados | Exibe um resumo com 10 linhas e colunas visíveis |
Conversão de Strings | Converte strings para fatores por padrão | Mantém strings como caracteres |
Manuseio de Colunas | Apenas vetores, listas podem ser problemáticas | Permite listas, funções, outros tibbles |
Nomes de Colunas | Nomes devem ser únicos e sem espaços | Nomes podem ter espaços, ser duplicados, etc. |
Retorno de Subsetting ([ ) |
Pode retornar um vetor ou data frame | Sempre retorna um tibble |
Compatibilidade e Integração | Totalmente compatível com base R | Compatível, mas otimizado para uso com tidyverse |
Manipulação de Dados | Menos intuitivo para algumas operações. | Mais intuitivo e fácil de usar, especialmente com operações encadeadas. |
16.1.1 Criar e trabalhar com Tibbles
Criar um tibble
é semelhante a criar um data frame, mas com uma
sintaxe ligeiramente diferente que facilita a criação de colunas
complexas.
# Carregar o pacote tibble
library(tibble)
# Criando um tibble
tb <- tibble(
x = 1:5,
y = c("A", "B", "C", "D", "E"),
z = x * 2
)
print(tb)
## # A tibble: 5 × 3
## x y z
## <int> <chr> <dbl>
## 1 1 A 2
## 2 2 B 4
## 3 3 C 6
## 4 4 D 8
## 5 5 E 10
Também pode converter um data frame existente para um tibble usando a
função as_tibble()
:
16.2 Manipulação de Dados com dplyr
O dplyr
é um pacote fundamental no tidyverse
para manipulação de
dados em R. Ele proporciona uma sintaxe mais limpa e legível para
operações comuns em data frames e tibbles, como seleção, filtragem,
mutação (criação/modificação de colunas), ordenação e agrupamento de
dados.
As principais funções do dplyr
são:
select()
: Seleciona colunas de um data frame.arrange()
: Ordena as linhas de um data frame com base nos valores de uma ou mais colunas.filter()
: Filtra linhas com base em condições lógicas.mutate()
: Adiciona novas colunas ou modifica colunas existentes.group_by()
: Agrupa os dados com base nos valores de uma ou mais colunas.summarise()
: Resuma os dados, tipicamente usado apósgroup_by()
para calcular estatísticas agregadas.
Vamos explorar cada uma dessas funções usando o dataset starwars
disponível no pacote dplyr.
Assim, utilizaremos o objeto sw
para acessar os dados.
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
## Rows: 87
## Columns: 14
## $ name <chr> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Leia Or…
## $ height <int> 172, 167, 96, 202, 150, 178, 165, 97, 183, 182, 188, 180, 2…
## $ mass <dbl> 77.0, 75.0, 32.0, 136.0, 49.0, 120.0, 75.0, 32.0, 84.0, 77.…
## $ hair_color <chr> "blond", NA, NA, "none", "brown", "brown, grey", "brown", N…
## $ skin_color <chr> "fair", "gold", "white, blue", "white", "light", "light", "…
## $ eye_color <chr> "blue", "yellow", "red", "yellow", "brown", "blue", "blue",…
## $ birth_year <dbl> 19.0, 112.0, 33.0, 41.9, 19.0, 52.0, 47.0, NA, 24.0, 57.0, …
## $ sex <chr> "male", "none", "none", "male", "female", "male", "female",…
## $ gender <chr> "masculine", "masculine", "masculine", "masculine", "femini…
## $ homeworld <chr> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Alderaan", "T…
## $ species <chr> "Human", "Droid", "Droid", "Human", "Human", "Human", "Huma…
## $ films <list> <"A New Hope", "The Empire Strikes Back", "Return of the J…
## $ vehicles <list> <"Snowspeeder", "Imperial Speeder Bike">, <>, <>, <>, "Imp…
## $ starships <list> <"X-wing", "Imperial shuttle">, <>, <>, "TIE Advanced x1",…
16.2.1 Seleção de Colunas com select()
A função select()
é usada para selecionar uma ou mais colunas de um
tibble ou data frame. Pode usar nomes de colunas diretamente sem aspas.
## # A tibble: 87 × 1
## name
## <chr>
## 1 Luke Skywalker
## 2 C-3PO
## 3 R2-D2
## 4 Darth Vader
## 5 Leia Organa
## 6 Owen Lars
## 7 Beru Whitesun Lars
## 8 R5-D4
## 9 Biggs Darklighter
## 10 Obi-Wan Kenobi
## # ℹ 77 more rows
## # A tibble: 87 × 3
## name mass hair_color
## <chr> <dbl> <chr>
## 1 Luke Skywalker 77 blond
## 2 C-3PO 75 <NA>
## 3 R2-D2 32 <NA>
## 4 Darth Vader 136 none
## 5 Leia Organa 49 brown
## 6 Owen Lars 120 brown, grey
## 7 Beru Whitesun Lars 75 brown
## 8 R5-D4 32 <NA>
## 9 Biggs Darklighter 84 black
## 10 Obi-Wan Kenobi 77 auburn, white
## # ℹ 77 more rows
## # A tibble: 87 × 4
## name height mass hair_color
## <chr> <int> <dbl> <chr>
## 1 Luke Skywalker 172 77 blond
## 2 C-3PO 167 75 <NA>
## 3 R2-D2 96 32 <NA>
## 4 Darth Vader 202 136 none
## 5 Leia Organa 150 49 brown
## 6 Owen Lars 178 120 brown, grey
## 7 Beru Whitesun Lars 165 75 brown
## 8 R5-D4 97 32 <NA>
## 9 Biggs Darklighter 183 84 black
## 10 Obi-Wan Kenobi 182 77 auburn, white
## # ℹ 77 more rows
O dplyr
possui um conjunto de funções auxiliares muito úteis para
seleção de colunas. As principais são:
starts_with()
: para colunas que começam com um texto específico.ends_with()
: para colunas que terminam com um texto específico.contains()
: para colunas que contêm um texto específico.
## # A tibble: 87 × 3
## hair_color skin_color eye_color
## <chr> <chr> <chr>
## 1 blond fair blue
## 2 <NA> gold yellow
## 3 <NA> white, blue red
## 4 none white yellow
## 5 brown light brown
## 6 brown, grey light blue
## 7 brown light blue
## 8 <NA> white, red red
## 9 black light brown
## 10 auburn, white fair blue-gray
## # ℹ 77 more rows
Para remover colunas, basta acrescentar um -
antes da seleção.
## # A tibble: 87 × 12
## height mass skin_color eye_color birth_year sex gender homeworld species
## <int> <dbl> <chr> <chr> <dbl> <chr> <chr> <chr> <chr>
## 1 172 77 fair blue 19 male mascu… Tatooine Human
## 2 167 75 gold yellow 112 none mascu… Tatooine Droid
## 3 96 32 white, blue red 33 none mascu… Naboo Droid
## 4 202 136 white yellow 41.9 male mascu… Tatooine Human
## 5 150 49 light brown 19 female femin… Alderaan Human
## 6 178 120 light blue 52 male mascu… Tatooine Human
## 7 165 75 light blue 47 female femin… Tatooine Human
## 8 97 32 white, red red NA none mascu… Tatooine Droid
## 9 183 84 light brown 24 male mascu… Tatooine Human
## 10 182 77 fair blue-gray 57 male mascu… Stewjon Human
## # ℹ 77 more rows
## # ℹ 3 more variables: films <list>, vehicles <list>, starships <list>
## # A tibble: 87 × 11
## name height mass birth_year sex gender homeworld species films vehicles
## <chr> <int> <dbl> <dbl> <chr> <chr> <chr> <chr> <lis> <list>
## 1 Luke S… 172 77 19 male mascu… Tatooine Human <chr> <chr>
## 2 C-3PO 167 75 112 none mascu… Tatooine Droid <chr> <chr>
## 3 R2-D2 96 32 33 none mascu… Naboo Droid <chr> <chr>
## 4 Darth … 202 136 41.9 male mascu… Tatooine Human <chr> <chr>
## 5 Leia O… 150 49 19 fema… femin… Alderaan Human <chr> <chr>
## 6 Owen L… 178 120 52 male mascu… Tatooine Human <chr> <chr>
## 7 Beru W… 165 75 47 fema… femin… Tatooine Human <chr> <chr>
## 8 R5-D4 97 32 NA none mascu… Tatooine Droid <chr> <chr>
## 9 Biggs … 183 84 24 male mascu… Tatooine Human <chr> <chr>
## 10 Obi-Wa… 182 77 57 male mascu… Stewjon Human <chr> <chr>
## # ℹ 77 more rows
## # ℹ 1 more variable: starships <list>
16.2.2 Exercícios
Utilize a base sw
nos exercícios a seguir.
1. Utilize a função glimpse()
do pacote dplyr
na base sw
. O
que ela faz?
2. Crie uma tabela chamada sw_simples
contendo apenas as colunas
name
, gender
e films
.
3. Selecione apenas as colunas hair_color
, skin_color
e
eye_color
usando a função auxiliar contains()
.
4. Usando a função select()
e as suas funções auxiliares, escreva
códigos que retornem a base sw
sem as colunas hair_color
,
skin_color
e eye_color
. Escreva todas as soluções diferentes que
conseguir pensar.
16.2.3 Ordenando a Base de Dados
A função arrange()
permite ordenar as linhas de uma tabela com base
nos valores de uma ou mais colunas. Pode ordenar em ordem crescente ou
decrescente, conforme a necessidade.
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Ratts T… 79 15 none grey, blue unknown NA male mascu…
## 2 Yoda 66 17 white green brown 896 male mascu…
## 3 Wicket … 88 20 brown brown brown 8 male mascu…
## 4 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 5 R5-D4 97 32 <NA> white, red red NA none mascu…
## 6 Sebulba 112 40 none grey, red orange NA male mascu…
## 7 Padmé A… 185 45 brown light brown 46 fema… femin…
## 8 Dud Bolt 94 45 none blue, grey yellow NA male mascu…
## 9 Wat Tam… 193 48 none green, gr… unknown NA male mascu…
## 10 Sly Moo… 178 48 none pale white NA <NA> <NA>
## # ℹ 77 more rows
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Jabba D… 175 1358 <NA> green-tan… orange 600 herm… mascu…
## 2 Grievous 216 159 none brown, wh… green, y… NA male mascu…
## 3 IG-88 200 140 none metal red 15 none mascu…
## 4 Darth V… 202 136 none white yellow 41.9 male mascu…
## 5 Tarfful 234 136 brown brown blue NA male mascu…
## 6 Owen La… 178 120 brown, gr… light blue 52 male mascu…
## 7 Bossk 190 113 none green red 53 male mascu…
## 8 Chewbac… 228 112 brown unknown blue 200 male mascu…
## 9 Jek Ton… 180 110 brown fair blue NA <NA> <NA>
## 10 Dexter … 198 102 none brown yellow NA male mascu…
## # ℹ 77 more rows
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Yarael … 264 NA none white yellow NA male mascu…
## 2 Tarfful 234 136 brown brown blue NA male mascu…
## 3 Lama Su 229 88 none grey black NA male mascu…
## 4 Chewbac… 228 112 brown unknown blue 200 male mascu…
## 5 Roos Ta… 224 82 none grey orange NA male mascu…
## 6 Grievous 216 159 none brown, wh… green, y… NA male mascu…
## 7 Taun We 213 NA none grey black NA fema… femin…
## 8 Tion Me… 206 80 none grey black NA male mascu…
## 9 Rugor N… 206 NA none green orange NA male mascu…
## 10 Darth V… 202 136 none white yellow 41.9 male mascu…
## # ℹ 77 more rows
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
16.2.4 Exercícios
1. Ordene a base sw
pela coluna mass
em ordem crescente e pela
coluna birth_year
em ordem decrescente. Guarde o resultado em um
objeto chamado sw_ordenados
.
2. Selecione apenas as colunas name
e birth_year
, então ordene
de forma decrescente pelo birth_year
.
16.2.5 Filtrando Linhas da Base de Dados
Para selecionar linhas específicas com base em uma ou mais condições,
utilizamos a função filter()
.
## # A tibble: 55 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke Sk… 172 77 blond fair blue 19 male mascu…
## 2 Darth V… 202 136 none white yellow 41.9 male mascu…
## 3 Owen La… 178 120 brown, gr… light blue 52 male mascu…
## 4 Biggs D… 183 84 black light brown 24 male mascu…
## 5 Obi-Wan… 182 77 auburn, w… fair blue-gray 57 male mascu…
## 6 Anakin … 188 84 blond fair blue 41.9 male mascu…
## 7 Wilhuff… 180 NA auburn, g… fair blue 64 male mascu…
## 8 Chewbac… 228 112 brown unknown blue 200 male mascu…
## 9 Han Solo 180 80 brown fair brown 29 male mascu…
## 10 Greedo 173 74 <NA> green black 44 male mascu…
## # ℹ 45 more rows
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
Podemos selecionar apenas as colunas name
e height
para
visualizarmos as alturas:
## # A tibble: 55 × 2
## name height
## <chr> <int>
## 1 Luke Skywalker 172
## 2 Darth Vader 202
## 3 Owen Lars 178
## 4 Biggs Darklighter 183
## 5 Obi-Wan Kenobi 182
## 6 Anakin Skywalker 188
## 7 Wilhuff Tarkin 180
## 8 Chewbacca 228
## 9 Han Solo 180
## 10 Greedo 173
## # ℹ 45 more rows
Podemos estender o filtro para duas ou mais colunas.
## # A tibble: 21 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Darth V… 202 136 none white yellow 41.9 male mascu…
## 2 Owen La… 178 120 brown, gr… light blue 52 male mascu…
## 3 Biggs D… 183 84 black light brown 24 male mascu…
## 4 Anakin … 188 84 blond fair blue 41.9 male mascu…
## 5 Chewbac… 228 112 brown unknown blue 200 male mascu…
## 6 Jabba D… 175 1358 <NA> green-tan… orange 600 herm… mascu…
## 7 Jek Ton… 180 110 brown fair blue NA <NA> <NA>
## 8 IG-88 200 140 none metal red 15 none mascu…
## 9 Bossk 190 113 none green red 53 male mascu…
## 10 Ackbar 180 83 none brown mot… orange 41 male mascu…
## # ℹ 11 more rows
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
## # A tibble: 21 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Darth V… 202 136 none white yellow 41.9 male mascu…
## 2 Owen La… 178 120 brown, gr… light blue 52 male mascu…
## 3 Biggs D… 183 84 black light brown 24 male mascu…
## 4 Anakin … 188 84 blond fair blue 41.9 male mascu…
## 5 Chewbac… 228 112 brown unknown blue 200 male mascu…
## 6 Jabba D… 175 1358 <NA> green-tan… orange 600 herm… mascu…
## 7 Jek Ton… 180 110 brown fair blue NA <NA> <NA>
## 8 IG-88 200 140 none metal red 15 none mascu…
## 9 Bossk 190 113 none green red 53 male mascu…
## 10 Ackbar 180 83 none brown mot… orange 41 male mascu…
## # ℹ 11 more rows
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
Podemos filtrar colunas categóricas. O exemplo abaixo retorna uma tabela apenas com os personagens com cabelo preto ou castanho.
## # A tibble: 31 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Leia Or… 150 49 brown light brown 19 fema… femin…
## 2 Beru Wh… 165 75 brown light blue 47 fema… femin…
## 3 Biggs D… 183 84 black light brown 24 male mascu…
## 4 Chewbac… 228 112 brown unknown blue 200 male mascu…
## 5 Han Solo 180 80 brown fair brown 29 male mascu…
## 6 Wedge A… 170 77 brown fair hazel 21 male mascu…
## 7 Jek Ton… 180 110 brown fair blue NA <NA> <NA>
## 8 Boba Fe… 183 78.2 black fair brown 31.5 male mascu…
## 9 Lando C… 177 79 black dark brown 31 male mascu…
## 10 Arvel C… NA NA brown fair brown NA male mascu…
## # ℹ 21 more rows
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
## # A tibble: 31 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Leia Or… 150 49 brown light brown 19 fema… femin…
## 2 Beru Wh… 165 75 brown light blue 47 fema… femin…
## 3 Biggs D… 183 84 black light brown 24 male mascu…
## 4 Chewbac… 228 112 brown unknown blue 200 male mascu…
## 5 Han Solo 180 80 brown fair brown 29 male mascu…
## 6 Wedge A… 170 77 brown fair hazel 21 male mascu…
## 7 Jek Ton… 180 110 brown fair blue NA <NA> <NA>
## 8 Boba Fe… 183 78.2 black fair brown 31.5 male mascu…
## 9 Lando C… 177 79 black dark brown 31 male mascu…
## 10 Arvel C… NA NA brown fair brown NA male mascu…
## # ℹ 21 more rows
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
Para filtrar textos sem correspondência exata, podemos utilizar a função
auxiliar str_detect()
do pacote {stringr}
. Ela serve para verificar
se cada string de um vetor contém um determinado padrão de texto.
## [1] TRUE TRUE TRUE FALSE FALSE NA
Podemos utilizá-la para filtrar apenas os personagens com cabelo grey
.
# Podemos detetar se o cabelo grey aparece na string
str_detect(
string = sw$hair_color,
pattern = "grey"
)
## [1] FALSE NA NA FALSE FALSE TRUE FALSE NA FALSE FALSE FALSE TRUE
## [13] FALSE FALSE NA NA FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [85] FALSE FALSE FALSE
## # A tibble: 3 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Owen Lars 178 120 brown, gr… light blue 52 male mascu…
## 2 Wilhuff … 180 NA auburn, g… fair blue 64 male mascu…
## 3 Palpatine 170 75 grey pale yellow 82 male mascu…
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
16.2.6 Exercícios
Utilize a base sw
nos exercícios a seguir.
1. Crie um objeto chamado humanos
apenas com personagens que sejam
humanos.
2. Crie um objeto chamado altos_fortes
com personagens que tenham
mais de 200 cm de altura e peso maior que 100 kg.
3. Retorne tabelas (tibbles
) apenas com:
a. Personagens humanos que nasceram antes de 100 anos antes da
batalha de Yavin (birth_year < 100
).
b. Personagens com cor light
ou red
.
c. Personagens com massa maior que 100 kg, ordenados de forma
decrescente por altura, mostrando apenas as colunas name
, mass
e
height
.
d. Personagens que sejam “Humano” ou “Droid”, e tenham uma altura maior que 170 cm.
e. Personagens que não possuem informação tanto de altura (height
)
quanto de massa (mass
), ou seja, possuem NA
em ambas as colunas.
16.2.7 Modificar e criar novas colunas
A função mutate()
permite criar novas colunas ou modificar colunas
existentes, facilitando transformações de dados. O código abaixo divide
os valores da coluna height
por 100, mudando a unidade de medida dessa
variável de centímetros para metros.
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <dbl> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke Sk… 1.72 77 blond fair blue 19 male mascu…
## 2 C-3PO 1.67 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 0.96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth V… 2.02 136 none white yellow 41.9 male mascu…
## 5 Leia Or… 1.5 49 brown light brown 19 fema… femin…
## 6 Owen La… 1.78 120 brown, gr… light blue 52 male mascu…
## 7 Beru Wh… 1.65 75 brown light blue 47 fema… femin…
## 8 R5-D4 0.97 32 <NA> white, red red NA none mascu…
## 9 Biggs D… 1.83 84 black light brown 24 male mascu…
## 10 Obi-Wan… 1.82 77 auburn, w… fair blue-gray 57 male mascu…
## # ℹ 77 more rows
## # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
Também poderíamos ter criado essa variável em uma nova coluna. Repare
que a nova coluna height_meters
é colocada no final da tabela.
## # A tibble: 87 × 15
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke Sk… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth V… 202 136 none white yellow 41.9 male mascu…
## 5 Leia Or… 150 49 brown light brown 19 fema… femin…
## 6 Owen La… 178 120 brown, gr… light blue 52 male mascu…
## 7 Beru Wh… 165 75 brown light blue 47 fema… femin…
## 8 R5-D4 97 32 <NA> white, red red NA none mascu…
## 9 Biggs D… 183 84 black light brown 24 male mascu…
## 10 Obi-Wan… 182 77 auburn, w… fair blue-gray 57 male mascu…
## # ℹ 77 more rows
## # ℹ 6 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>, height_meters <dbl>
Podemos fazer qualquer operação com uma ou mais colunas. Abaixo vamos
criar um tibble que contenha as colunas name
, height
, mass
, e uma
nova coluna BMI
, que calcule o Índice de Massa Corporal (IMC) de cada
personagem, usando a fórmula mass / (height/100)^2
. Caso height
ou
mass
seja NA
, a coluna BMI
deve ser NA
.
sw %>%
mutate(BMI = ifelse(!is.na(height) & !is.na(mass), mass / (height/100)^2, NA)) %>%
select(name, height, mass, BMI)
## # A tibble: 87 × 4
## name height mass BMI
## <chr> <int> <dbl> <dbl>
## 1 Luke Skywalker 172 77 26.0
## 2 C-3PO 167 75 26.9
## 3 R2-D2 96 32 34.7
## 4 Darth Vader 202 136 33.3
## 5 Leia Organa 150 49 21.8
## 6 Owen Lars 178 120 37.9
## 7 Beru Whitesun Lars 165 75 27.5
## 8 R5-D4 97 32 34.0
## 9 Biggs Darklighter 183 84 25.1
## 10 Obi-Wan Kenobi 182 77 23.2
## # ℹ 77 more rows
16.2.8 Exercícios
1. Crie uma coluna chamada dif_peso_altura
(diferença entre altura
e peso) e salve a nova tabela em um objeto chamado starwars_dif
. Em
seguida, filtre apenas os personagens que têm altura maior que o peso e
ordene a tabela por ordem crescente de dif_peso_altura
.
2. Crie as seguintes colunas:
a. indice_massa_altura
= mass
/ height
b. indice_massa_medio
= mean(mass, na.rm = TRUE)
c. indice_relativo
=
(indice_massa_altura - indice_massa_medio) / indice_massa_medio
d. acima_media
=
ifelse(indice_massa_altura > indice_massa_medio, “sim”, “não”)
3. Crie uma nova coluna que classifique o personagem em “recente” (nascido após 100 anos antes da batalha de Yavin) e “antigo” (nascido há 100 anos ou mais).
16.2.9 Sumarizar a Base de Dados
A função summarize()
permite calcular estatísticas agregadas, como
média, mediana, variância, etc. Para agregar dados por categorias,
combinamos summarize()
com group_by()
.
O código abaixo resume a coluna mass
pela sua média.
## # A tibble: 1 × 1
## media_massa
## <dbl>
## 1 97.3
# Sumarização agrupada por categorias
sw %>%
group_by(species) %>%
summarize(media_massa = mean(mass, na.rm = TRUE))
## # A tibble: 38 × 2
## species media_massa
## <chr> <dbl>
## 1 Aleena 15
## 2 Besalisk 102
## 3 Cerean 82
## 4 Chagrian NaN
## 5 Clawdite 55
## 6 Droid 69.8
## 7 Dug 40
## 8 Ewok 20
## 9 Geonosian 80
## 10 Gungan 74
## # ℹ 28 more rows
Podemos calcular ao mesmo tempo sumarizações diferentes.
sw %>% summarize(
media_massa = mean(mass, na.rm = TRUE),
mediana_massa = median(mass, na.rm = TRUE),
variancia_massa = var(mass, na.rm = TRUE)
)
## # A tibble: 1 × 3
## media_massa mediana_massa variancia_massa
## <dbl> <dbl> <dbl>
## 1 97.3 79 28716.
Podemos também sumarizar diversas colunas.
sw %>% summarize(
media_massa = mean(mass, na.rm = TRUE),
media_altura = mean(height, na.rm = TRUE),
media_ano = mean(birth_year, na.rm = TRUE)
)
## # A tibble: 1 × 3
## media_massa media_altura media_ano
## <dbl> <dbl> <dbl>
## 1 97.3 175. 87.6
Para sumarizar uma coluna agrupada pelas categorias de uma segunda
coluna usamos além do summarize()
a função group_by()
.
O código a abaixo calcula a altura média dos personagens para cada
categoria da coluna hair_color
.
sw %>%
filter(!is.na(hair_color), !is.na(height)) %>%
group_by(hair_color) %>%
summarize(media_altura = mean(height, na.rm = TRUE))
## # A tibble: 11 × 2
## hair_color media_altura
## <chr> <dbl>
## 1 auburn 150
## 2 auburn, grey 180
## 3 auburn, white 182
## 4 black 174.
## 5 blond 177.
## 6 blonde 168
## 7 brown 177.
## 8 brown, grey 178
## 9 grey 170
## 10 none 181.
## 11 white 156
16.2.10 Exerícios
Utilize a base sw
nos exercícios a seguir.
1. Calcule a altura média e mediana dos personagens.
2. Calcule a massa média dos personagens cuja altura é maior que 175 cm.
3. Apresente na mesma tabela a massa média dos personagens com altura menor que 175 cm e a massa média dos personagens com altura maior ou igual a 175 cm.
4. Retorne tabelas (tibbles
) apenas com:
a. A altura média dos personagens por espécie. b. A massa média e mediana dos personagens por espécie. c. Apenas o nome dos personagens que participaram de mais de 2 filmes.
16.2.11 Juntando Tabelas em R com dplyr
Em ciência de dados, é comum precisar combinar informações de diferentes
fontes em uma única tabela. No R, o pacote dplyr
oferece várias
funções para realizar operações de junção, que permitem combinar duas ou
mais tabelas (data frames ou tibbles) com base em uma ou mais colunas
compartilhadas.
Tipos de Junção
As junções mais comuns em manipulação de dados são:
left_join()
: Mantém todas as linhas da tabela à esquerda e adiciona as colunas da tabela à direita onde há correspondência de valores na coluna chave.right_join()
: Mantém todas as linhas da tabela à direita e adiciona as colunas da tabela à esquerda onde há correspondência.full_join()
: Mantém todas as linhas de ambas as tabelas e adiciona NA onde não há correspondência.
Essas funções são extremamente úteis quando é necessário combinar dados de diferentes fontes que compartilham uma chave comum, como um identificador único.
Exemplo: Personagens de Star Wars
Para ilustrar como estas funções funcionam, vamos usar a base de dados
sw
e criar dois subconjuntos de dados:
personagens_altos
: Tabela contendo apenas personagens com altura superior a 180 cm.personagens_humanos
: Tabela contendo apenas personagens que são humanos.
Vamos criar os nossos subconjuntos de dados usando a função filter()
do dplyr.
# Criar subconjunto de personagens altos (altura > 180 cm)
personagens_altos <- sw %>%
filter(height > 180) %>%
select(name, height)
# Criar subconjunto de personagens humanos
personagens_humanos <- sw %>%
filter(species == "Human") %>%
select(name, species)
Agora que temos duas tabelas, personagens_altos
e
personagens_humanos
, podemos usar as funções de junção para
combiná-las: left_join()
, right_join()
, e full_join()
.
A função left_join()
junta duas tabelas, mantendo todas as linhas da
tabela à esquerda (primeira tabela) e adicionando colunas da tabela à
direita (segunda tabela) para as quais existe uma correspondência.
Valores sem correspondência entre as bases receberão NA
na nova base.
# Combinar tabelas mantendo todas as linhas de personagens_altos
humanos_altos_left_join <- left_join(personagens_altos, personagens_humanos, by = "name")
# Visualizar o resultado
print(humanos_altos_left_join)
## # A tibble: 39 × 3
## name height species
## <chr> <int> <chr>
## 1 Darth Vader 202 Human
## 2 Biggs Darklighter 183 Human
## 3 Obi-Wan Kenobi 182 Human
## 4 Anakin Skywalker 188 Human
## 5 Chewbacca 228 <NA>
## 6 Boba Fett 183 Human
## 7 IG-88 200 <NA>
## 8 Bossk 190 <NA>
## 9 Qui-Gon Jinn 193 Human
## 10 Nute Gunray 191 <NA>
## # ℹ 29 more rows
Neste exemplo, a tabela resultante humanos_altos_left_join
inclui
todos os personagens altos e adiciona informações sobre a espécie (se
disponível) da tabela personagens_humanos
. Se um personagem não for
humano, as colunas de espécie serão preenchidas com NA
.
A função right_join()
faz o oposto de left_join()
: mantém todas as
linhas da tabela à direita e adiciona colunas da tabela à esquerda para
as quais existe uma correspondência.
# Combinar tabelas mantendo todas as linhas de personagens_humanos
humanos_altos_right_join <- right_join(personagens_altos, personagens_humanos, by = "name")
# Visualizar o resultado
print(humanos_altos_right_join)
## # A tibble: 35 × 3
## name height species
## <chr> <int> <chr>
## 1 Darth Vader 202 Human
## 2 Biggs Darklighter 183 Human
## 3 Obi-Wan Kenobi 182 Human
## 4 Anakin Skywalker 188 Human
## 5 Boba Fett 183 Human
## 6 Qui-Gon Jinn 193 Human
## 7 Padmé Amidala 185 Human
## 8 Ric Olié 183 Human
## 9 Quarsh Panaka 183 Human
## 10 Mace Windu 188 Human
## # ℹ 25 more rows
A tabela humanos_altos_right_join
inclui todos os personagens humanos
e adiciona informações sobre a altura (se disponível) da tabela
personagens_altos
. Se um personagem humano não for alto, a coluna de
altura será preenchida com NA
.
A função full_join()
mantém todas as linhas de ambas as tabelas e
adiciona NA
onde não há correspondência.
# Combinar todas as informações de personagens altos e humanos
humanos_altos_full_join <- full_join(personagens_altos, personagens_humanos, by = "name")
# Visualizar o resultado
print(humanos_altos_full_join)
## # A tibble: 59 × 3
## name height species
## <chr> <int> <chr>
## 1 Darth Vader 202 Human
## 2 Biggs Darklighter 183 Human
## 3 Obi-Wan Kenobi 182 Human
## 4 Anakin Skywalker 188 Human
## 5 Chewbacca 228 <NA>
## 6 Boba Fett 183 Human
## 7 IG-88 200 <NA>
## 8 Bossk 190 <NA>
## 9 Qui-Gon Jinn 193 Human
## 10 Nute Gunray 191 <NA>
## # ℹ 49 more rows
A tabela humanos_altos_full_join
contém todos os personagens altos e
humanos. Se um personagem está em apenas uma das tabelas, as colunas da
outra tabela são preenchidas com NA
.
16.2.12 Exercícios
1. Crie uma tabela personagens_altos
contendo apenas personagens
com altura superior a 180 cm e uma outra tabela personagens_leves
contendo apenas personagens com massa inferior a 75 kg. Use
left_join()
para combinar as duas tabelas com base no nome do
personagem.
# Criação dos subconjuntos
personagens_altos <- sw %>%
filter(height > 180) %>%
select(name, height)
personagens_leves <- sw %>%
filter(mass < 75) %>%
select(name, mass)
# Combinação com left_join
left_join(personagens_altos, personagens_leves, by = "name")
Dica: Observe como left_join()
mantém todos os personagens altos e
adiciona informações sobre massa apenas para aqueles que também são
leves.
2. Crie uma tabela personagens_humanos
contendo apenas personagens
humanos e uma outra tabela cor_cabelo
contendo apenas personagens com
cor de cabelo diferente de NA
. Use right_join()
para combinar
personagens_humanos
e cor_cabelo
com base no nome do personagem.
# Criação dos subconjuntos
personagens_humanos <- sw %>%
filter(species == "Human") %>%
select(name, species)
cor_cabelo <- sw %>%
filter(!is.na(hair_color)) %>%
select(name, hair_color,)
# Combinação com right_join
right_join(personagens_humanos, cor_cabelo, by = "name")
Dica: Observe como right_join()
mantém todos os personagens com
cor de cabelo conhecida e adiciona informações sobre a espécie apenas
para aqueles que também são humanos.
3. Crie uma tabela especies_personagens
contendo apenas
personagens de espécies conhecidas (não NA
) e uma outra tabela
cor_olhos
contendo apenas personagens com cor de olho conhecida (não
NA
). Use full_join()
para combinar as duas tabelas com base no nome
do personagem.
# Criação dos subconjuntos
especies_personagens <- sw %>%
filter(!is.na(species)) %>%
select(name, species)
cor_olhos <- sw %>%
filter(!is.na(eye_color)) %>%
select(name, eye_color)
# Combinação com full_join
full_join(especies_personagens, cor_olhos, by = "name")
Dica: full_join()
combina todas as informações disponíveis,
preenchendo com NA onde não há correspondências.