Você está na página 1de 8

Hackeando o R e Python

Agrupando e Juntando dados no R


Luiz Henrique Barbosa Filho

22/06/2022

As ferramentas mais poderosas para a Análise de dados com o R estão contidas no pacote {dplyr},
parte da família do {tidyverse}, que proporciona verbs (funções), que ajudam o usuário a re-
solver problemas de manipulação de dados de forma extremamente simples. Neste post de hoje,
mostraremos, através do principais verbs do pacote, como é possível agregar e juntar dados.

Agregação

Agregação de dados é basicamente agregar observações de categorias referenciadas em uma coluna,


ou mesmo, agregar diversas colunas, para realizar operações, em geral matemáticas e estatísticas,
de forma que possamos resumir informações.
Os dois verbos principais para agregar e realizar operações do {dplyr}, respectivamente, são o
group_by() e summarise(). Com group_by(), agrupamos a coluna inserida dentro da função. Em
seguida, utilizamos a função summarise(), para escolhermos o nome da nova coluna a ser criada e
a referenciamos em conjunto com a função da operação matemática ou estatística que desejamos
escolhendo a coluna que queremos aplicar o calculo. Abaixo, utilizamos o dataset iris, que contém
amostras sobre tamanhos de sépalas e pétalas de três diferentes espécies de flores como exemplos.
Neste primeiro exemplo, agrupamos as observações da coluna Species, ou seja, agrupamos as três
espécies diferentes (categorias das observações), em seguida, utilizamos summarise(), escolhendo
o nome da nova coluna, que será mean_petal, e calculamos a média da coluna Petal.Length com
mean(). O resultado será a média de Petal.Length para cada espécie.

library(dplyr)

####### Agregação ######


# Transforma em tibble

1
iris_tbl <-
iris %>%
tibble()

iris_tbl

## # A tibble: 150 x 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 5 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## # ... with 140 more rows

Nem sempre é necessário utilizarmos summarise, como no exemplo abaixo, no qual a função count()
permite calcular a contagem do número de observações do data frame, porém, agrupados pelas
categorias de Species.

# Agrupa por Species e calcula a média de Petal.Length


iris_tbl %>%
group_by(Species) %>%
summarise(mean_petal = mean(Petal.Length))

## # A tibble: 3 x 2
## Species mean_petal
## <fct> <dbl>
## 1 setosa 1.46
## 2 versicolor 4.26
## 3 virginica 5.55

Nem sempre é necessário utilizarmos summarise, como no exemplo abaixo, no qual a função count()
permite calcular a contagem do número de observações do data frame, porém, agrupados pelas
categorias de Species.

# Agrupa Species e realiza a contagem de observações


iris_tbl %>%
group_by(Species) %>%
count()

## # A tibble: 3 x 2
## # Groups: Species [3]
## Species n

2
## <fct> <int>
## 1 setosa 50
## 2 versicolor 50
## 3 virginica 50

E se quisermos aplicar algum calcular para diversas colunas? Poderíamos nomear e realizar o cálculo
dentro de summarise para cada uma, entretanto, não seria viável caso tivéssemos inúmeras colunas
para calcular. Para tanto, podemos utilizar a função across(), que permite aplicar a função do
cálculo para cada coluna do data frame que escolhermos. Abaixo, escolhemos a coluna Sepal.Length
até Petal.Width, utilizando dois pontos (:).
# Agrupa por Species e calcula a média de Sepal.Length até Petal.Width
iris_tbl %>%
group_by(Species) %>%
summarise(across(Sepal.Length:Petal.Width, mean))

## # A tibble: 3 x 5
## Species Sepal.Length Sepal.Width Petal.Length Petal.Width
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 setosa 5.01 3.43 1.46 0.246
## 2 versicolor 5.94 2.77 4.26 1.33
## 3 virginica 6.59 2.97 5.55 2.03

# Agrupa por Species e calcula o desvio padrão de Sepal.Length até Petal.Width


iris_tbl %>%
group_by(Species) %>%
summarise(across(Sepal.Length:Petal.Width, sd))

## # A tibble: 3 x 5
## Species Sepal.Length Sepal.Width Petal.Length Petal.Width
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 setosa 0.352 0.379 0.174 0.105
## 2 versicolor 0.516 0.314 0.470 0.198
## 3 virginica 0.636 0.322 0.552 0.275

A função across() também permite que sejam aplicadas condições para o cálculo de colunas em
conjunto com outros verbs. Vejamos abaixo a utilização de where(), que permite utilizarmos uma
condição para a aplicação da função. A condição colocada em where() é de que para toda coluna
numérica (is.numeric()), seja aplicado o cálculo da média. O ~ em mean, significa que toda a
operação à esquerda do operador seja em função do parte direita, isto é, será aplicado a média para
toda a condição satisfeita.
# Agrupa Species e calcula a média de coluna numéricas
iris_tbl %>%
group_by(Species) %>%
summarise(across(where(is.numeric), ~ mean(.x, na.rm = TRUE)))

## # A tibble: 3 x 5
## Species Sepal.Length Sepal.Width Petal.Length Petal.Width
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 setosa 5.01 3.43 1.46 0.246
## 2 versicolor 5.94 2.77 4.26 1.33
## 3 virginica 6.59 2.97 5.55 2.03

3
Juntar dados

É quase certeza que ao trabalhar com dados, iremos nos deparar com a missão de juntar data
frames. Por sorte, o pacote {dplyr} também nos fornece formas de juntar diferentes data frames.
Os verbs utilizados para realizar esse procedimento são conhecidos como _joins(). Cada um com
um nome diferente, possuindo um comportamento único.
A ideia principal do _joins é simples: a junção do data frame só pode ocorrer caso eles tenham
colunas com observações em comum, de forma que eles sejam relacionais.
Utilizaremos os datasets do pacote {nycflights13}, contendo os datasets flights e airports.
Começaremos selecionando apenas algumas colunas do dataset flights para que possamos diminuir
o seu tamanho.

### juntando

library(nycflights13)

# left_join

flights_r <- flights %>%


select(year, month, day, dep_time, arr_delay, carrier)

flights_r

## # A tibble: 336,776 x 6
## year month day dep_time arr_delay carrier
## <int> <int> <int> <int> <dbl> <chr>
## 1 2013 1 1 517 11 UA
## 2 2013 1 1 533 20 UA
## 3 2013 1 1 542 33 AA
## 4 2013 1 1 544 -18 B6
## 5 2013 1 1 554 -25 DL
## 6 2013 1 1 554 12 UA
## 7 2013 1 1 555 19 B6
## 8 2013 1 1 557 -14 EV
## 9 2013 1 1 557 -8 B6
## 10 2013 1 1 558 8 AA
## # ... with 336,766 more rows

Nosso objetivo aqui será juntar o data frame flights_r com o data frame airports, para que possamos
encontrar os voos que se relacionam com os aeroportos através das transportadores aéreas (coluna
carrier).

airlines

## # A tibble: 16 x 2
## carrier name
## <chr> <chr>
## 1 9E Endeavor Air Inc.
## 2 AA American Airlines Inc.

4
## 3 AS Alaska Airlines Inc.
## 4 B6 JetBlue Airways
## 5 DL Delta Air Lines Inc.
## 6 EV ExpressJet Airlines Inc.
## 7 F9 Frontier Airlines Inc.
## 8 FL AirTran Airways Corporation
## 9 HA Hawaiian Airlines Inc.
## 10 MQ Envoy Air
## 11 OO SkyWest Airlines Inc.
## 12 UA United Air Lines Inc.
## 13 US US Airways Inc.
## 14 VX Virgin America
## 15 WN Southwest Airlines Co.
## 16 YV Mesa Airlines Inc.

Para juntar as colunas em comum, podemos utilizar o left_join, como o nome diz, juntaremos as
observações da coluna do data frame da esquerda, para encaixar na coluna em comum com o data
frame da direita. Exemplificando: inner_join(x, y…) Temos que x é o data frame da esquerda, e y
é o data frame da direita. Abaixo, juntamos as colunas de flights_r em airlines.

left join

# Junta os dados de airlines em flights

flights_r %>%
left_join(airlines)

## # A tibble: 336,776 x 7
## year month day dep_time arr_delay carrier name
## <int> <int> <int> <int> <dbl> <chr> <chr>
## 1 2013 1 1 517 11 UA United Air Lines Inc.
## 2 2013 1 1 533 20 UA United Air Lines Inc.
## 3 2013 1 1 542 33 AA American Airlines Inc.
## 4 2013 1 1 544 -18 B6 JetBlue Airways
## 5 2013 1 1 554 -25 DL Delta Air Lines Inc.
## 6 2013 1 1 554 12 UA United Air Lines Inc.
## 7 2013 1 1 555 19 B6 JetBlue Airways
## 8 2013 1 1 557 -14 EV ExpressJet Airlines Inc.
## 9 2013 1 1 557 -8 B6 JetBlue Airways
## 10 2013 1 1 558 8 AA American Airlines Inc.
## # ... with 336,766 more rows

# Escolhe a coluna que deseja juntar (caso possua o mesmo nome)

flights_r %>%
left_join(airlines, by = "carrier")

## # A tibble: 336,776 x 7
## year month day dep_time arr_delay carrier name

5
## <int> <int> <int> <int> <dbl> <chr> <chr>
## 1 2013 1 1 517 11 UA United Air Lines Inc.
## 2 2013 1 1 533 20 UA United Air Lines Inc.
## 3 2013 1 1 542 33 AA American Airlines Inc.
## 4 2013 1 1 544 -18 B6 JetBlue Airways
## 5 2013 1 1 554 -25 DL Delta Air Lines Inc.
## 6 2013 1 1 554 12 UA United Air Lines Inc.
## 7 2013 1 1 555 19 B6 JetBlue Airways
## 8 2013 1 1 557 -14 EV ExpressJet Airlines Inc.
## 9 2013 1 1 557 -8 B6 JetBlue Airways
## 10 2013 1 1 558 8 AA American Airlines Inc.
## # ... with 336,766 more rows

Veja que citamos também o argumento by = “carrier” no segundo exemplo. Esse procedimento
é utilizado caso seja necessário especificar o nome da coluna para que a função reconhece qual
desejamos juntar.

right join

Caso quisermos realizar o procedimento contrário de left_join(), utilizamos o right_join(). Abaixo


o exemplo possui um resultado similar, a diferença é que está sendo juntado as observações da
direita na da esquerda.

# Junta os dados de flights em airlines

flights_r %>%
right_join(airlines)

## # A tibble: 336,776 x 7
## year month day dep_time arr_delay carrier name
## <int> <int> <int> <int> <dbl> <chr> <chr>
## 1 2013 1 1 517 11 UA United Air Lines Inc.
## 2 2013 1 1 533 20 UA United Air Lines Inc.
## 3 2013 1 1 542 33 AA American Airlines Inc.
## 4 2013 1 1 544 -18 B6 JetBlue Airways
## 5 2013 1 1 554 -25 DL Delta Air Lines Inc.
## 6 2013 1 1 554 12 UA United Air Lines Inc.
## 7 2013 1 1 555 19 B6 JetBlue Airways
## 8 2013 1 1 557 -14 EV ExpressJet Airlines Inc.
## 9 2013 1 1 557 -8 B6 JetBlue Airways
## 10 2013 1 1 558 8 AA American Airlines Inc.
## # ... with 336,766 more rows

# Escolhe a coluna que deseja juntar (caso possua o mesmo nome)

flights_r %>%
right_join(airlines, by = "carrier")

## # A tibble: 336,776 x 7
## year month day dep_time arr_delay carrier name

6
## <int> <int> <int> <int> <dbl> <chr> <chr>
## 1 2013 1 1 517 11 UA United Air Lines Inc.
## 2 2013 1 1 533 20 UA United Air Lines Inc.
## 3 2013 1 1 542 33 AA American Airlines Inc.
## 4 2013 1 1 544 -18 B6 JetBlue Airways
## 5 2013 1 1 554 -25 DL Delta Air Lines Inc.
## 6 2013 1 1 554 12 UA United Air Lines Inc.
## 7 2013 1 1 555 19 B6 JetBlue Airways
## 8 2013 1 1 557 -14 EV ExpressJet Airlines Inc.
## 9 2013 1 1 557 -8 B6 JetBlue Airways
## 10 2013 1 1 558 8 AA American Airlines Inc.
## # ... with 336,766 more rows

inner join

E caso quisermos juntar os dados em comum de ambos os data frame, sem exceção? Podemos
utilizar o verb inner_join(). Abaixo, utilizando os data sets band_members e band_instrument,
juntamos a coluna name, para observações em comum de ambos os data frames.

band_members

## # A tibble: 3 x 2
## name band
## <chr> <chr>
## 1 Mick Stones
## 2 John Beatles
## 3 Paul Beatles

band_instruments

## # A tibble: 3 x 2
## name plays
## <chr> <chr>
## 1 John guitar
## 2 Paul bass
## 3 Keith guitar

band_members %>%
inner_join(band_instruments)

## # A tibble: 2 x 3
## name band plays
## <chr> <chr> <chr>
## 1 John Beatles guitar
## 2 Paul Beatles bass

7
full join

E para juntar todos os dados? Podemos utilizar o verb full_join, abaixo, juntamos todos os dados de
band_members e band_instruments2, veja que desta vez especificamos a coluna para ser juntada,
devido ao fato de que band_instruments2 possui a coluna de nomes diferentes.

# full_join
# Junta todos os dados dos dois data frames
band_members %>%
full_join(band_instruments2,
by = c("name" = "artist"))

## # A tibble: 4 x 3
## name band plays
## <chr> <chr> <chr>
## 1 Mick Stones <NA>
## 2 John Beatles guitar
## 3 Paul Beatles bass
## 4 Keith <NA> guitar

Você também pode gostar