Antes de iniciar, vamos instalar o pacote tidyverse
, que é uma coleção de bibliotecas criadas para o universo de análise de dados.
install.packages("tidyverse")
library(tidyverse)
Veja todos os pacotes disponíveis em www.tidyverse.org. O pacote dplyr
faz parte do universo tidyverse
.
magrittr
A função deste operar é passar o objeto do lado esquerdo como primeiro argumento da função do lado direito:
x %>% f(y)
é equivalente a f(x,y)
y %>% f(x,.,z)
é equivalente a f(x,y,z)
Atalho no teclado: Ctrl + Shift + M
Na prática, vamos supor que queremos somar todos os elementos do vetor
e em seguida tirar a raiz quadrada desta soma:
vetor <- c(20, 40, 60, 80, 200)
sqrt(sum(vetor))
## [1] 20
Usando o pipe:
vetor %>% sum() %>% sqrt()
## [1] 20
dplyr
Os cinco principais verbos do pacote dplyr
são:
select()
: seleciona colunas de um dataframefilter()
: filtra linhas que satisfazem uma condição lógicaarrange()
: ordena as linhas de acordo com uma colunamutate()
: cria novas colunassummarize()
: sumariza as informaçõesTodas as funções com estes verbos os funcionam de maneira similar:
Vamos considerar a base de dados flights
do pacote nycflights13
, que lista todos os voos que partiram dos aeroportos da cidade de Nova York em 2013.
library(nycflights13)
data(flights)
A primeira função que vamos ver não se encontra da lista dos principais verbos mencionada acima. Veja a documentalção da função slice
(comando: ?slice
).
flights %>%
slice_head(n = 5)
year | month | day | dep_time | sched_dep_time | dep_delay | arr_time | sched_arr_time | arr_delay | carrier | flight | tailnum | origin | dest | air_time | distance | hour | minute | time_hour |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2013 | 1 | 1 | 517 | 515 | 2 | 830 | 819 | 11 | UA | 1545 | N14228 | EWR | IAH | 227 | 1400 | 5 | 15 | 2013-01-01 05:00:00 |
2013 | 1 | 1 | 533 | 529 | 4 | 850 | 830 | 20 | UA | 1714 | N24211 | LGA | IAH | 227 | 1416 | 5 | 29 | 2013-01-01 05:00:00 |
2013 | 1 | 1 | 542 | 540 | 2 | 923 | 850 | 33 | AA | 1141 | N619AA | JFK | MIA | 160 | 1089 | 5 | 40 | 2013-01-01 05:00:00 |
2013 | 1 | 1 | 544 | 545 | -1 | 1004 | 1022 | -18 | B6 | 725 | N804JB | JFK | BQN | 183 | 1576 | 5 | 45 | 2013-01-01 05:00:00 |
2013 | 1 | 1 | 554 | 600 | -6 | 812 | 837 | -25 | DL | 461 | N668DN | LGA | ATL | 116 | 762 | 6 | 0 | 2013-01-01 06:00:00 |
select
()Vamos selecionar quatro colunas específicas da base de dados: carrier
, year
, month
e day
.
flights %>%
select(carrier, year, month, day)
Podemos selecionar todas as colunas, com exceção de algumas, como por exemplo a coluna year
.
flights %>%
select(-year)
everything()
é útil para mover as colunas de lugar ao fazer uma seleção.
flights %>%
select(carrier, origin, everything())
Também podemos renomear uma coluna dentro do select
.
flights %>%
select("ano" = year, month, day)
filter()
Vamos obter somente os dados de voos ocorridos em 01/01/2013.
flights %>% filter(month == 1, day == 1)
Abaixo, outro exemplo de filtro: voos partindo dos aeroportos JF Kennedy ou Newark com destino a Los Angeles.
flights %>%
filter(origin %in% c("JFK", "EWR"), dest == "LAX")
arrange()
O código a seguir arranja os dados segundo a ordem crescente da coluna dep_delay
.
flights %>%
arrange(dep_delay)
Agora usando a ordem decrescente.
flights %>%
arrange(desc(dep_delay))
Se você fornecer mais de uma coluna, as demais colunas serão usadas sucessivamente para decidir os empates.
flights %>%
arrange(desc(month), day)
filter()
, select()
e arrange()
Vamos verificar qual a companhia aérea que teve o voo com maior atraso nos vôos entre JFK e LAX.
flights %>%
filter(origin == "JFK", dest == "LAX") %>%
select(carrier, dep_delay, year, month, day) %>%
arrange(desc(dep_delay)) %>%
slice_head(n = 1)
A tabela airlines
, também do pacote nycflights13
, contém o nome completo das companhias e o respectivo código que aparece na tabela flights
.
data(airlines)
airlines %>%
filter(carrier == "DL")
mutate()
Vamos criar uma variável que mostre a velocidade de cada voo.
flights %>%
select(year:day, flight, distance, air_time) %>%
mutate(speed = distance / (air_time / 60))
Note que você também pode se referir às variáveis que criou:
flights %>%
select(year:day, flight, distance, air_time) %>%
mutate(hours = air_time / 60,
speed = distance / hours)
Para manter apenas as variáveis calculadas, use transmute
().
flights %>%
select(year:day, ends_with("delay"), distance, air_time) %>%
transmute(hours = air_time / 60,
speed = distance / hours)
Note que é equivalente a %>% select(hours, speed)
no final do código anterior.
summarise()
Vamos calcular o atraso médio de decolagem e a quantidade total de voos.
flights %>%
filter(!is.na(dep_delay)) %>%
summarise(mean_delay = mean(dep_delay),
number_of_flights = n())
group_by()
Vamos calcular o atraso médio de decolagem e a quantidade total de voos, mas agora analisando por companhia aérea e ordenar pela companhia que apresentou o maior atraso médio.
flights %>%
filter(!is.na(dep_delay)) %>%
group_by(carrier) %>%
summarise(mean_delay = mean(dep_delay), number_of_flights = n()) %>%
arrange(desc(mean_delay))
O código abaixo calcula, para cada destino, a distância média dos voos, o tempo de atraso médio na decolagem e o número de voos na base.
flights %>%
filter(!is.na(distance), !is.na(dep_delay)) %>%
group_by(dest) %>%
summarise(count = n(),
distance = mean(distance),
delay = mean(dep_delay))
O código abaixo faz um gráfico de barras que mostra os destinos que apresentaram os maiores atrasos médios. Para obter o nome dos aeroportos, mesclamos esses dados com a tabela airports
.
library(ggplot2)
flights %>%
filter(!is.na(arr_delay)) %>%
group_by(dest) %>%
summarise(delay = mean(arr_delay)) %>%
merge(airports, by.x = "dest", by.y="faa") %>%
mutate(name = fct_reorder(name, delay)) %>%
slice_max(delay, n = 15) %>%
ggplot(aes(name, delay))+
geom_col()+
coord_flip()+
labs(x = NULL,
y = "Delay (minutes)")+
theme_minimal()
Dados organizados em formato tidy são facilmente usados para análise e modelagem.
Regras que definem um conjunto de dados tidy [{1}]:
O formato de uma tabela tidy depende do que são considerados variável e observação em um dado contexto.
Como exemplo, veja os dados de casos de tuberculose em diferentes paises, armazenados no pacote tidyr
.
library(tidyr)
table1
country | year | cases | population |
---|---|---|---|
Afghanistan | 1999 | 745 | 19987071 |
Afghanistan | 2000 | 2666 | 20595360 |
Brazil | 1999 | 37737 | 172006362 |
Brazil | 2000 | 80488 | 174504898 |
China | 1999 | 212258 | 1272915272 |
China | 2000 | 213766 | 1280428583 |
Veja como é simples calcular a taxa de casos por população.
table1 %>%
mutate(rate = cases / population * 10000)
table4a
country | 1999 | 2000 |
---|---|---|
Afghanistan | 745 | 2666 |
Brazil | 37737 | 80488 |
China | 212258 | 213766 |
O que devemos fazer para deixar essa tabela no formato tidy?
Podemos usar a função pivot_longer
.
table4a %>%
pivot_longer(cols = -country,
names_to = "year",
values_to = "cases")
Agora, veja este próximo caso.
table2
country | year | type | count |
---|---|---|---|
Afghanistan | 1999 | cases | 745 |
Afghanistan | 1999 | population | 19987071 |
Afghanistan | 2000 | cases | 2666 |
Afghanistan | 2000 | population | 20595360 |
Brazil | 1999 | cases | 37737 |
Brazil | 1999 | population | 172006362 |
Brazil | 2000 | cases | 80488 |
Brazil | 2000 | population | 174504898 |
China | 1999 | cases | 212258 |
China | 1999 | population | 1272915272 |
China | 2000 | cases | 213766 |
China | 2000 | population | 1280428583 |
O que devemos fazer para deixar essa tabela no formato tidy?
Podemos usar a função pivot_wider
.
table2 %>%
pivot_wider(names_from = type,
values_from = count)
[1]. Wickham, H. Tidy data. Journal of statistical software, v. 59, n. 1, p. 1-23, 2014.
[2]. Todas figuras foram retiradas do livro R for Data Science Wickham, H. and Grolemund, G. 2017.