Manipulação de dados com o pacote dplyr

Inovação Tecnológica e Processos de Desenvolvimento

Anderson Ribeiro Duarte

Introdução

Foram discutidas formas de importar os dados para o R, com origens em diversas fontes. A aquisição de dados da web por meio de leitura direta e webscrapping. Também foram apresentados os principais problemas relacionados à bases de dados e algumas formas de saná-los. O processo realizado por essas etapas é um pré-processamento. Na metodologia de ETL como base, foi concluída a fase do E (extract).

Introdução

Supondo que os dados antes do pré-processamento fossem considerados a “matéria-prima”, esta matéria prima agora já estaria um pouco mais refinada e poderia passar por um processo de transformação em um produto intermediário.

O processo seguinte é justamente este processo de transformação dos dados em um produto mais adequado para gerar os resultados finais, sejam eles indicadores (KPIs), relatórios descritivos (BI) ou modelos complexos (classificação, regressão, etc).

Introdução

Neste momento, em que os dados já se encontram em uma estrutura organizada, para fornecer as informações necessárias, algumas transformações são importantes. As mais comuns envolvem a criação de novas variáveis, sumarização as informações, alteração nos títulos dos dados de forma que eles se tornem mais compreensíveis, reordenar os dados, dentre outras operações.

Aplicação

Algumas operações voltadas à transformação de dados serão apresentadas, divididas em três tópicos principais: Linhas, colunas e agrupamento.

Os dados de voos flights, do pacote nycflights13, serão utilizados, um banco que compila 336.776 vôos que partiram da cidade de Nova Iorque no ano de 2013. A descrição do conjunto de dados pode ser obtida via comando ?flights.

Aplicação

#Carrega o pacote nycflights13
pacman::p_load(nycflights13)

#Estrutura dos dados
glimpse(flights)
Rows: 336,776
Columns: 19
$ year           <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2…
$ month          <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ day            <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ dep_time       <int> 517, 533, 542, 544, 554, 554, 555, 557, 557, 558, 558, …
$ sched_dep_time <int> 515, 529, 540, 545, 600, 558, 600, 600, 600, 600, 600, …
$ dep_delay      <dbl> 2, 4, 2, -1, -6, -4, -5, -3, -3, -2, -2, -2, -2, -2, -1…
$ arr_time       <int> 830, 850, 923, 1004, 812, 740, 913, 709, 838, 753, 849,…
$ sched_arr_time <int> 819, 830, 850, 1022, 837, 728, 854, 723, 846, 745, 851,…
$ arr_delay      <dbl> 11, 20, 33, -18, -25, 12, 19, -14, -8, 8, -2, -3, 7, -1…
$ carrier        <chr> "UA", "UA", "AA", "B6", "DL", "UA", "B6", "EV", "B6", "…
$ flight         <int> 1545, 1714, 1141, 725, 461, 1696, 507, 5708, 79, 301, 4…
$ tailnum        <chr> "N14228", "N24211", "N619AA", "N804JB", "N668DN", "N394…
$ origin         <chr> "EWR", "LGA", "JFK", "JFK", "LGA", "EWR", "EWR", "LGA",…
$ dest           <chr> "IAH", "IAH", "MIA", "BQN", "ATL", "ORD", "FLL", "IAD",…
$ air_time       <dbl> 227, 227, 160, 183, 116, 150, 158, 53, 140, 138, 149, 1…
$ distance       <dbl> 1400, 1416, 1089, 1576, 762, 719, 1065, 229, 944, 733, …
$ hour           <dbl> 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6…
$ minute         <dbl> 15, 29, 40, 45, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0…
$ time_hour      <dttm> 2013-01-01 05:00:00, 2013-01-01 05:00:00, 2013-01-01 0…

Aplicação

Com o conjunto de dados, inicia-se o estudo de transformação de dados usando o pacote dplyr. O pacote dplyr é organizado em três grupos principais, com base nos elementos em que ele opera:

  • Linhas;

  • Colunas;

  • Grupos.

Observe separadamente os principais verbos para cada um destes elementos.

Linhas

Na estrutura tidy, cada linha representa uma observação, um indivíduo. Neste sentido, as principais operações com linhas tendem a ser aquelas nas quais as características de cada observação seja relevante. Tais operações afetam apenas as linhas e mantém a informação das colunas inalteradas. As principais são:

  • filter();

  • arrange();

  • distinct().

A função distinct() diferente das duas primeiras, em alguns casos pode afetar as colunas.

filter()

A função filter(), conforme o próprio nome indica, permite a seleção de linhas com base em atributos presentes nas colunas, ou seja, uma filtragem com base nas características dos dados. O primeiro atributo é um data frame. Os demais argumentos são condições, que devem ser verdadeiras para que as observações sejam mantidas na filtragem. Por exemplo, vamos filtrar todos os vôos que duraram menos de 120 minutos.

#Voos que duraram menos de 120 minutos
flights %>% filter(air_time < 120)
# A tibble: 147,003 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      554            600        -6      812            837
 2  2013     1     1      557            600        -3      709            723
 3  2013     1     1      559            559         0      702            706
 4  2013     1     1      602            605        -3      821            805
 5  2013     1     1      629            630        -1      721            740
 6  2013     1     1      629            630        -1      824            833
 7  2013     1     1      632            608        24      740            728
 8  2013     1     1      639            640        -1      739            749
 9  2013     1     1      643            645        -2      837            848
10  2013     1     1      645            647        -2      815            810
# ℹ 146,993 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

filter()

A função pode ser utilizada com todos os operadores de comparação disponíveis no R,

  • > maior que;

  • >= maior ou igual que;

  • < menor que;

  • <= menor ou igual que;

  • == igual a;

  • != diferente de;

filter()

Também podem ser agrupadas com os operadores & e |. Além destes operadores, outro uso interessante ocorre em conjunto com o operador %in%, que mantém todos os valores que pertencem a um determinado vetor, alguns exemplos:

    #Seleção dos vôos que partiram após o mês de abril
    flights %>% 
      filter(month > 4)
# A tibble: 227,657 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013    10     1      447            500       -13      614            648
 2  2013    10     1      522            517         5      735            757
 3  2013    10     1      536            545        -9      809            855
 4  2013    10     1      539            545        -6      801            827
 5  2013    10     1      539            545        -6      917            933
 6  2013    10     1      544            550        -6      912            932
 7  2013    10     1      549            600       -11      653            716
 8  2013    10     1      550            600       -10      648            700
 9  2013    10     1      550            600       -10      649            659
10  2013    10     1      551            600        -9      727            730
# ℹ 227,647 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

filter()

    #Voos que partiram no dia 03 de junho
    flights %>% 
      filter(month == 6 & day == 3)
# A tibble: 982 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     6     3        3           2359         4      338            345
 2  2013     6     3       10           2115       175      150           2310
 3  2013     6     3       13           2359        14      619            350
 4  2013     6     3      512            515        -3      739            811
 5  2013     6     3      518            500        18      654            640
 6  2013     6     3      534            540        -6      842            840
 7  2013     6     3      541            545        -4      904            922
 8  2013     6     3      542            545        -3      810            827
 9  2013     6     3      550            550         0      833            845
10  2013     6     3      553            600        -7      658            700
# ℹ 972 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

filter()

    #Voos com destino nos aeroportos ALB ou DAY
    flights %>% 
      filter(dest == "ALB" | dest == "DAY")
# A tibble: 1,964 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1     1304           1227        37     1518           1422
 2  2013     1     1     1315           1317        -2     1413           1423
 3  2013     1     1     1655           1621        34     1804           1724
 4  2013     1     1     1732           1630        62     2028           1825
 5  2013     1     1     2056           2004        52     2156           2112
 6  2013     1     2      834            823        11     1039           1018
 7  2013     1     2     1228           1229        -1     1430           1424
 8  2013     1     2     1332           1327         5     1419           1433
 9  2013     1     2     1746           1621        85     1835           1724
10  2013     1     2     1909           1621       168     2116           1816
# ℹ 1,954 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

filter()

    #Mesma seleção anterior, utilizando a função %in%
    flights %>% 
      filter(dest %in% c("ALB", "DAY"))
# A tibble: 1,964 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1     1304           1227        37     1518           1422
 2  2013     1     1     1315           1317        -2     1413           1423
 3  2013     1     1     1655           1621        34     1804           1724
 4  2013     1     1     1732           1630        62     2028           1825
 5  2013     1     1     2056           2004        52     2156           2112
 6  2013     1     2      834            823        11     1039           1018
 7  2013     1     2     1228           1229        -1     1430           1424
 8  2013     1     2     1332           1327         5     1419           1433
 9  2013     1     2     1746           1621        85     1835           1724
10  2013     1     2     1909           1621       168     2116           1816
# ℹ 1,954 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

filter()

O pacote base possui uma função que realiza o mesmo trabalho, a função subset(). A função base tende a ser mais rápida que a função filter() em bancos de dados menores. Entretanto, a função filter apresenta desempenho superior em bancos de dados de maior dimensão. Outra vantagem da função do pacote dlpyr() é que ela trabalha com bancos de dados SQL, o que a função base não faz.

arrange()

A função arrange() altera o ordenamento das linhas com base em uma ou mais colunas, ou ainda expressões baseadas em colunas. Caso sejam informadas duas ou mais colunas, as colunas posteriores à primeira serão utilizadas para desempatar a ordem. Como exemplo, ordenar os vôos pela data de partida e utilizar o horário de partida para desempatar as ocorrências.

arrange()

#Voos ordenados por data de partida
flights %>% 
  arrange(year, month, day, desc(dep_time))
# A tibble: 336,776 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1     2356           2359        -3      425            437
 2  2013     1     1     2353           2359        -6      425            445
 3  2013     1     1     2353           2359        -6      418            442
 4  2013     1     1     2343           1724       379      314           1938
 5  2013     1     1     2327           2250        37       32           2359
 6  2013     1     1     2326           2130       116      131             18
 7  2013     1     1     2323           2200        83       22           2313
 8  2013     1     1     2312           2000       192       21           2110
 9  2013     1     1     2310           2255        15       24             15
10  2013     1     1     2307           2245        22       32           2357
# ℹ 336,766 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

arrange()

É possível usar a função desc() dentro da função arrange() para escolher a ordenação decrescente das variáveis de interesse, alguns exemplos de utilização da função.

#Voos ordenados por ordem decrescente de atraso na partida
flights %>% 
  arrange(desc(dep_delay))
# A tibble: 336,776 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     9      641            900      1301     1242           1530
 2  2013     6    15     1432           1935      1137     1607           2120
 3  2013     1    10     1121           1635      1126     1239           1810
 4  2013     9    20     1139           1845      1014     1457           2210
 5  2013     7    22      845           1600      1005     1044           1815
 6  2013     4    10     1100           1900       960     1342           2211
 7  2013     3    17     2321            810       911      135           1020
 8  2013     6    27      959           1900       899     1236           2226
 9  2013     7    22     2257            759       898      121           1026
10  2013    12     5      756           1700       896     1058           2020
# ℹ 336,766 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

arrange()

#Voos ordenados por distância decrescente e tempo de voo crescente
flights %>% 
  arrange(desc(distance), air_time)
# A tibble: 336,776 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     5     7      959           1000        -1     1401           1500
 2  2013     6     6     1044           1000        44     1441           1435
 3  2013     9    29      957           1000        -3     1405           1445
 4  2013     6     7      952           1000        -8     1354           1435
 5  2013     6     8      951           1000        -9     1352           1435
 6  2013     9     6      955           1000        -5     1359           1445
 7  2013     2    26     1000            900        60     1513           1540
 8  2013     5     6      956           1000        -4     1358           1500
 9  2013     9    28      955           1000        -5     1412           1445
10  2013     7     3      957           1000        -3     1410           1430
# ℹ 336,766 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

distinct()

A função distinct() remove, se existirem, as linhas duplicadas em um conjunto de dados. Ao aplicar a função, ele mantém a primeira observação duplicada e elimina as posteriores. Para verificar todas as duplicatas, basta utilizar a função sem parâmetros.

#Remoção de todas as linhas duplicadas
count(flights)
# A tibble: 1 × 1
       n
   <int>
1 336776
flights %>% 
  distinct()
# A tibble: 336,776 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ℹ 336,766 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

distinct()

Note ocorreu alteração no número de linhas do conjunto de dados, logo, não existem duplicatas. É possível fornecer um subconjunto de colunas para a função distinct(). Neste caso, ela verificará duplicatas considerando apenas as colunas selecionadas. É possível, ao considerar o subconjunto de colunas, remover as duplicatas, porém manter as demais colunas. Pra tal, basta utilizar o argumento .keep_all = T.

#Valores distintos considerando origem e destino
flights %>% 
  distinct(origin, dest)
# A tibble: 224 × 2
   origin dest 
   <chr>  <chr>
 1 EWR    IAH  
 2 LGA    IAH  
 3 JFK    MIA  
 4 JFK    BQN  
 5 LGA    ATL  
 6 EWR    ORD  
 7 EWR    FLL  
 8 LGA    IAD  
 9 JFK    MCO  
10 LGA    ORD  
# ℹ 214 more rows

distinct()

#Valores distintos considerando origem e destino, com os demais dados
flights %>% 
  distinct(origin, dest, .keep_all = T)
# A tibble: 224 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ℹ 214 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

Note que, conforme mencionado, a função mantém a primeira observação duplicada. Por este motivo, muitas observações do dia 01 de janeiro aparecem.

Colunas

Ao se trabalhar com colunas, são quatro as funções principais: mutate(), select(), rename() e relocate(). A função mutate() cria novas colunas, enquanto a função select() seleciona colunas. A função rename() altera o nome de colunas e, por fim, a função relocate() altera a ordem das colunas no conjunto de dados. Vamos explorar cada uma das funções separadamente.

mutate()

A função mutate() tem como objetivo adicionar novas colunas ao banco de dados, calculadas das colunas já existentes. Ela opera com quaisquer outras funções aplicáveis às colunas que compõe os dados, alguns exemplos de sua aplicação.

#Cálculo da velocidade média de voo e tempo total de atraso
flights %>% 
  mutate(velocidade = distance / air_time * 60,
         atraso_total = dep_delay + arr_delay)
# A tibble: 336,776 × 21
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ℹ 336,766 more rows
# ℹ 13 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, velocidade <dbl>,
#   atraso_total <dbl>

mutate()

#Variável itinerário, com origem e destino e identificação do voo, com numero do voo e do aviao
flights %>% 
  mutate(itinerario = paste(origin, "-", dest),
         identificacao = paste(flight, "-", tailnum))
# A tibble: 336,776 × 21
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ℹ 336,766 more rows
# ℹ 13 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, itinerario <chr>,
#   identificacao <chr>

mutate()

Por padrão, a função mutate() adiciona as variáveis criadas são adicionadas ao final do banco de dados. entretanto, é possível selecionar a posição das novas colunas com o uso dos argumentos .before e .after, procedidos da coluna que servirá como referência. Os argumentos são precedidos de pontos para não ser interpretados como novas colunas. Observe os exemplos anteriores para compreender o uso dos argumentos.

mutate()

#Cálculo da velocidade média de voo e tempo total de atraso, colocando as novas colunas no inicio do BD
flights %>% 
  mutate(velocidade = distance / air_time * 60,
         atraso_total = dep_delay + arr_delay,
         .before = year)
# A tibble: 336,776 × 21
   velocidade atraso_total  year month   day dep_time sched_dep_time dep_delay
        <dbl>        <dbl> <int> <int> <int>    <int>          <int>     <dbl>
 1       370.           13  2013     1     1      517            515         2
 2       374.           24  2013     1     1      533            529         4
 3       408.           35  2013     1     1      542            540         2
 4       517.          -19  2013     1     1      544            545        -1
 5       394.          -31  2013     1     1      554            600        -6
 6       288.            8  2013     1     1      554            558        -4
 7       404.           14  2013     1     1      555            600        -5
 8       259.          -17  2013     1     1      557            600        -3
 9       405.          -11  2013     1     1      557            600        -3
10       319.            6  2013     1     1      558            600        -2
# ℹ 336,766 more rows
# ℹ 13 more variables: arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
#   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
#   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

mutate()

#Variável itinerário, com origem e destino e identificação do voo, com numero do voo e do aviao após o dia de voo
flights %>% 
  mutate(itinerario = paste(origin, "-", dest),
         identificacao = paste(flight, "-", tailnum),
         .after = day)
# A tibble: 336,776 × 21
    year month   day itinerario identificacao dep_time sched_dep_time dep_delay
   <int> <int> <int> <chr>      <chr>            <int>          <int>     <dbl>
 1  2013     1     1 EWR - IAH  1545 - N14228      517            515         2
 2  2013     1     1 LGA - IAH  1714 - N24211      533            529         4
 3  2013     1     1 JFK - MIA  1141 - N619AA      542            540         2
 4  2013     1     1 JFK - BQN  725 - N804JB       544            545        -1
 5  2013     1     1 LGA - ATL  461 - N668DN       554            600        -6
 6  2013     1     1 EWR - ORD  1696 - N39463      554            558        -4
 7  2013     1     1 EWR - FLL  507 - N516JB       555            600        -5
 8  2013     1     1 LGA - IAD  5708 - N829AS      557            600        -3
 9  2013     1     1 JFK - MCO  79 - N593JB        557            600        -3
10  2013     1     1 LGA - ORD  301 - N3ALAA       558            600        -2
# ℹ 336,766 more rows
# ℹ 13 more variables: arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
#   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
#   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

mutate()

Outro argumento útil na função é o .keep. É possível manter todas as colunas (.keep = "all"), apenas as colunas usadas no cálculo das novas (keep = "used"), remover as colunas utilizadas no cálculo (.keep = "unused") ou manter apenas as colunas calculadas (.keep = "none"). Por padrão todas as variáveis são mantidas. Observe a diferença em cada parâmetro.

#Retem apenas as variáveis usadas e criadas
flights %>% 
  mutate(velocidade = distance / air_time * 60,
         atraso_total = dep_delay + arr_delay,
         .keep = "used")
# A tibble: 336,776 × 6
   dep_delay arr_delay air_time distance velocidade atraso_total
       <dbl>     <dbl>    <dbl>    <dbl>      <dbl>        <dbl>
 1         2        11      227     1400       370.           13
 2         4        20      227     1416       374.           24
 3         2        33      160     1089       408.           35
 4        -1       -18      183     1576       517.          -19
 5        -6       -25      116      762       394.          -31
 6        -4        12      150      719       288.            8
 7        -5        19      158     1065       404.           14
 8        -3       -14       53      229       259.          -17
 9        -3        -8      140      944       405.          -11
10        -2         8      138      733       319.            6
# ℹ 336,766 more rows

mutate()

#Retem as variáveis criadas e exclui as usadas
flights %>% 
  mutate(velocidade = distance / air_time * 60,
         atraso_total = dep_delay + arr_delay,
         .keep = "unused")
# A tibble: 336,776 × 17
    year month   day dep_time sched_dep_time arr_time sched_arr_time carrier
   <int> <int> <int>    <int>          <int>    <int>          <int> <chr>  
 1  2013     1     1      517            515      830            819 UA     
 2  2013     1     1      533            529      850            830 UA     
 3  2013     1     1      542            540      923            850 AA     
 4  2013     1     1      544            545     1004           1022 B6     
 5  2013     1     1      554            600      812            837 DL     
 6  2013     1     1      554            558      740            728 UA     
 7  2013     1     1      555            600      913            854 B6     
 8  2013     1     1      557            600      709            723 EV     
 9  2013     1     1      557            600      838            846 B6     
10  2013     1     1      558            600      753            745 AA     
# ℹ 336,766 more rows
# ℹ 9 more variables: flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, velocidade <dbl>,
#   atraso_total <dbl>

mutate()

#Retem apenas as variaveis criadas
flights %>% 
  mutate(velocidade = distance / air_time * 60,
         atraso_total = dep_delay + arr_delay,
         .keep = "none")
# A tibble: 336,776 × 2
   velocidade atraso_total
        <dbl>        <dbl>
 1       370.           13
 2       374.           24
 3       408.           35
 4       517.          -19
 5       394.          -31
 6       288.            8
 7       404.           14
 8       259.          -17
 9       405.          -11
10       319.            6
# ℹ 336,766 more rows

mutate()

É importante notar que os objetos não foram atribuídos. Assim, os resultados foram apenas impressos. Para salvar o resultado é necessário criar um novo objeto, ou sobreescrever o conjunto de dados. A conduta dependerá do trabalho em andamento, entretanto, é uma prática recomendável a criação de um novo objeto, para ter os dados originais à mão, no caso de alguma alteração indesejada.

across()

Uma função bastante útil para ser conjugada com a função mutate é a função across(). Suponha que se deseja aplicar uma mesma transformação a um conjunto de variáveis. Para otimizar o processo, ao invés de criar uma série de variáveis de forma individual, a função across() permite que tal transformação seja aplicada em um conjunto de variáveis, vejas um exemplo de aplicação.

across()

Note que as variáveis terminadas com time apresentam um formato incomum. Apesar de representar um horário, elas estão em formato inteiro. Segundo a documentação do banco de dados, se trata de um formato HHMM ou HMM, também conhecido como formato militar, ou seja, 517 equivale a 5:17, 1125 equivale a 11:25 e assim sucessivamente.

across()

#Função para converter o formato em data-hora
conv <- function(x){
  h <- x%/%100
  m <- x-(100*h)
  min <- case_when(m < 10 ~ paste0("0", m),
                   .default = as.character(m))
  
  return(paste0(h, ":", min))
}


flights %>% mutate(
  across(.cols = c(dep_time, sched_dep_time, arr_time, sched_arr_time), 
         .fn = conv, .names = "conv_{.col}")) 
# A tibble: 336,776 × 23
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ℹ 336,766 more rows
# ℹ 15 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, conv_dep_time <chr>,
#   conv_sched_dep_time <chr>, conv_arr_time <chr>, conv_sched_arr_time <chr>

across()

Foram utilizados três parâmetros: .cols para identificar as colunas nas quais a transformação ocorrerá, .fn que indica que função(ões) aplicar e .names para definir como as novas variáveis serão nomeadas. Note que utilizamos o argumento {.col} para agregar à string o nome original da coluna. Caso não utilizemos o parâmetro .names, a nova variável sobreescreverá a variável antiga.

select()

Uma das tarefas mais comuns ao se trabalhar com bancos de dados, é a seleção das variáveis de interesse. Muitas vezes, recebemos bancos de dados com uma série de variáveis que não são úteis na ocasião, o que exige a manutenção de apenas uma parcela das informações disponíveis. A função select() facilita tal seleção.

select()

A função trabalha com uma série de possibilidades, como:

  • Selecionar colunas por nome:

    #Seleciona colunas year, flight, origin, dest
    flights %>% 
      select(year, flight, origin, dest)
    # A tibble: 336,776 × 4
        year flight origin dest 
       <int>  <int> <chr>  <chr>
     1  2013   1545 EWR    IAH  
     2  2013   1714 LGA    IAH  
     3  2013   1141 JFK    MIA  
     4  2013    725 JFK    BQN  
     5  2013    461 LGA    ATL  
     6  2013   1696 EWR    ORD  
     7  2013    507 EWR    FLL  
     8  2013   5708 LGA    IAD  
     9  2013     79 JFK    MCO  
    10  2013    301 LGA    ORD  
    # ℹ 336,766 more rows

    select()

  • Selecionar colunas entre duas outras

    #Seleciona todas as colunas entre o horário de partida e o horário de chegada
    flights %>% 
      select(dep_time:arr_time)
    # A tibble: 336,776 × 4
       dep_time sched_dep_time dep_delay arr_time
          <int>          <int>     <dbl>    <int>
     1      517            515         2      830
     2      533            529         4      850
     3      542            540         2      923
     4      544            545        -1     1004
     5      554            600        -6      812
     6      554            558        -4      740
     7      555            600        -5      913
     8      557            600        -3      709
     9      557            600        -3      838
    10      558            600        -2      753
    # ℹ 336,766 more rows

    select()

  • Selecionar colunas exceto aquelas entre duas outras

    #Seleciona todas as colunas exceto aquelas entre o horário de partida e o horário de chegada
    flights %>% 
      select(!dep_time:arr_time)
    # A tibble: 336,776 × 15
        year month   day sched_arr_time arr_delay carrier flight tailnum origin
       <int> <int> <int>          <int>     <dbl> <chr>    <int> <chr>   <chr> 
     1  2013     1     1            819        11 UA        1545 N14228  EWR   
     2  2013     1     1            830        20 UA        1714 N24211  LGA   
     3  2013     1     1            850        33 AA        1141 N619AA  JFK   
     4  2013     1     1           1022       -18 B6         725 N804JB  JFK   
     5  2013     1     1            837       -25 DL         461 N668DN  LGA   
     6  2013     1     1            728        12 UA        1696 N39463  EWR   
     7  2013     1     1            854        19 B6         507 N516JB  EWR   
     8  2013     1     1            723       -14 EV        5708 N829AS  LGA   
     9  2013     1     1            846        -8 B6          79 N593JB  JFK   
    10  2013     1     1            745         8 AA         301 N3ALAA  LGA   
    # ℹ 336,766 more rows
    # ℹ 6 more variables: dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
    #   minute <dbl>, time_hour <dttm>

    select()

  • Seleciona todas as colunas de determinada classe

    #Selecionar todas as colunas com caracteres
    flights %>% 
      select(where(is.character))
    # A tibble: 336,776 × 4
       carrier tailnum origin dest 
       <chr>   <chr>   <chr>  <chr>
     1 UA      N14228  EWR    IAH  
     2 UA      N24211  LGA    IAH  
     3 AA      N619AA  JFK    MIA  
     4 B6      N804JB  JFK    BQN  
     5 DL      N668DN  LGA    ATL  
     6 UA      N39463  EWR    ORD  
     7 B6      N516JB  EWR    FLL  
     8 EV      N829AS  LGA    IAD  
     9 B6      N593JB  JFK    MCO  
    10 AA      N3ALAA  LGA    ORD  
    # ℹ 336,766 more rows

    select()

  • Seleciona todas as colunas cujo nome começa com algum padrão

    #Seleciona todas as colunas que começam com "dep"
    flights %>% 
      select(starts_with("dep"))
    # A tibble: 336,776 × 2
       dep_time dep_delay
          <int>     <dbl>
     1      517         2
     2      533         4
     3      542         2
     4      544        -1
     5      554        -6
     6      554        -4
     7      555        -5
     8      557        -3
     9      557        -3
    10      558        -2
    # ℹ 336,766 more rows

    select()

  • Seleciona todas as colunas cujos nomes terminam com um padrão.

    #Seleciona todas as colunas que terminam com "delay"
    flights %>% 
      select(ends_with("delay"))
    # A tibble: 336,776 × 2
       dep_delay arr_delay
           <dbl>     <dbl>
     1         2        11
     2         4        20
     3         2        33
     4        -1       -18
     5        -6       -25
     6        -4        12
     7        -5        19
     8        -3       -14
     9        -3        -8
    10        -2         8
    # ℹ 336,766 more rows

    select()

  • Seleciona todas as colunas cujo nome contém um determinado padrão.

    #Seleciona todas as colunas que contem "arr_"
    flights %>% 
      select(contains("arr_"))
    # A tibble: 336,776 × 3
       arr_time sched_arr_time arr_delay
          <int>          <int>     <dbl>
     1      830            819        11
     2      850            830        20
     3      923            850        33
     4     1004           1022       -18
     5      812            837       -25
     6      740            728        12
     7      913            854        19
     8      709            723       -14
     9      838            846        -8
    10      753            745         8
    # ℹ 336,766 more rows

    select()

    Também é possível utilizar expressões regulares para selecionar colunas, por meio da função match().

Outra possibilidade que a função select fornece é a possibilidade de renomear as colunas ao selecioná-las. Basta colocar o novo nome da coluna antes do nome da coluna selecionada, separadas por um sinal de =.

#Selecionar a coluna dep_time e renomea-la para departure_time
flights %>% 
  select(departure_time = dep_time)
# A tibble: 336,776 × 1
   departure_time
            <int>
 1            517
 2            533
 3            542
 4            544
 5            554
 6            554
 7            555
 8            557
 9            557
10            558
# ℹ 336,766 more rows

rename()

A função rename(), como o próprio nome sugere, serve para renomear colunas. Seu uso é bastante direto e é aplicado quando se quer renomear uma série de variáveis, ao invés de o fazer por meio da seleção.

#Vamos renomear algumas colunas
flights %>% 
  rename(dia = day, mes = month, ano = year)
# A tibble: 336,776 × 19
     ano   mes   dia dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ℹ 336,766 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

relocate()

A função relocate() tem como objetivo reordenar colunas, pode ser utilizada para agrupar variáveis relacionadas em posições próximas, ou trazer para o início variáveis mais importantes. Por padrão, a função trás os valores para o início. Ao utilizar os argumentos .after e .before, é possível definir a posição das colunas antes ou depois determinadas variáveis.

#Trazer as variáveis air_time e distance para o início
flights %>% 
  relocate(air_time, distance)
# A tibble: 336,776 × 19
   air_time distance  year month   day dep_time sched_dep_time dep_delay
      <dbl>    <dbl> <int> <int> <int>    <int>          <int>     <dbl>
 1      227     1400  2013     1     1      517            515         2
 2      227     1416  2013     1     1      533            529         4
 3      160     1089  2013     1     1      542            540         2
 4      183     1576  2013     1     1      544            545        -1
 5      116      762  2013     1     1      554            600        -6
 6      150      719  2013     1     1      554            558        -4
 7      158     1065  2013     1     1      555            600        -5
 8       53      229  2013     1     1      557            600        -3
 9      140      944  2013     1     1      557            600        -3
10      138      733  2013     1     1      558            600        -2
# ℹ 336,766 more rows
# ℹ 11 more variables: arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
#   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

relocate()

#Mover as variáveis de origem e destino para antes do tempo de partida
flights %>% 
  relocate(origin:dest, .before = dep_time)
# A tibble: 336,776 × 19
    year month   day origin dest  dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int> <chr>  <chr>    <int>          <int>     <dbl>    <int>
 1  2013     1     1 EWR    IAH        517            515         2      830
 2  2013     1     1 LGA    IAH        533            529         4      850
 3  2013     1     1 JFK    MIA        542            540         2      923
 4  2013     1     1 JFK    BQN        544            545        -1     1004
 5  2013     1     1 LGA    ATL        554            600        -6      812
 6  2013     1     1 EWR    ORD        554            558        -4      740
 7  2013     1     1 EWR    FLL        555            600        -5      913
 8  2013     1     1 LGA    IAD        557            600        -3      709
 9  2013     1     1 JFK    MCO        557            600        -3      838
10  2013     1     1 LGA    ORD        558            600        -2      753
# ℹ 336,766 more rows
# ℹ 10 more variables: sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
#   flight <int>, tailnum <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

relocate()

#Mover as variáveis de tempo para depois do destino
flights %>% 
  relocate(dep_time:arr_delay, .after = dest)
# A tibble: 336,776 × 19
    year month   day carrier flight tailnum origin dest  dep_time sched_dep_time
   <int> <int> <int> <chr>    <int> <chr>   <chr>  <chr>    <int>          <int>
 1  2013     1     1 UA        1545 N14228  EWR    IAH        517            515
 2  2013     1     1 UA        1714 N24211  LGA    IAH        533            529
 3  2013     1     1 AA        1141 N619AA  JFK    MIA        542            540
 4  2013     1     1 B6         725 N804JB  JFK    BQN        544            545
 5  2013     1     1 DL         461 N668DN  LGA    ATL        554            600
 6  2013     1     1 UA        1696 N39463  EWR    ORD        554            558
 7  2013     1     1 B6         507 N516JB  EWR    FLL        555            600
 8  2013     1     1 EV        5708 N829AS  LGA    IAD        557            600
 9  2013     1     1 B6          79 N593JB  JFK    MCO        557            600
10  2013     1     1 AA         301 N3ALAA  LGA    ORD        558            600
# ℹ 336,766 more rows
# ℹ 9 more variables: dep_delay <dbl>, arr_time <int>, sched_arr_time <int>,
#   arr_delay <dbl>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
#   time_hour <dttm>

Grupos

Em muitas situações, é necessária uma abordagem em que os dados apresentem resultados para grupos distintos. Por exemplo, em uma pesquisa de opinião, podemos querer segmentar os resultados por características do público alvo, como renda, escolaridade, dentre outros.

O pacote dplyr oferece uma excelente opção para trabalhar com tais tipos de agrupamento, a função group_by(). Esta função, quando utilizada em conjunto com a função summarize(), é capaz de fornecer estatísticas de cada grupo. Exploração de cada uma delas, além de outras funções relacionadas a agrupamentos.

group_by()

A função group_by() divide os dados em grupos, ou seja, após agrupados, todas as análises serão realizadas levando em consideração o agrupamento definido.

#Agrupamento pela variável origin
flights %>% 
  group_by(origin)
# A tibble: 336,776 × 19
# Groups:   origin [3]
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ℹ 336,766 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

Aparentemente, não houve qualquer alteração nos dados, note que agora tem-se uma informação sobre o agrupamento. Ela indica que qualquer operação agora levará tal agrupamento em consideração.

summarize()

A operação mais importante em dados agrupados é definida pela função summarize(). Ela agrega os dados de modo que, as informações são resumidas a uma linha por grupo. Para compreender melhor sua utilização, vamos agora verificar o atraso médio na partida por aeroporto de origem. Como os dados contém dados faltantes, é necessário repassar o argumento na.rm = T para a função

#Atraso médio na partida por aeroporto de origem
flights %>% 
  group_by(origin) %>% 
  summarize(
    avg_delay = mean(dep_delay, na.rm = T)
  )
# A tibble: 3 × 2
  origin avg_delay
  <chr>      <dbl>
1 EWR         15.1
2 JFK         12.1
3 LGA         10.3

summarize()

É possivel calcular várias novas variáveis para o grupo definido. Suponha definir os atrasos mínimo, médio, mediano e máximo, bem como o desvio padrão e o número de viagens por aeroporto:

#Estatísticas descritivas para o atraso na partida
flights %>% 
  group_by(origin) %>% 
  summarize(
    min_delay = min(dep_delay, na.rm = T),
    avg_delay = mean(dep_delay, na.rm = T),
    median_delay = median(dep_delay, na.rm = T),
    max_delay = max(dep_delay, na.rm = T),
    sd_delay = sd(dep_delay, na.rm = T),
    n = n(),
  )
# A tibble: 3 × 7
  origin min_delay avg_delay median_delay max_delay sd_delay      n
  <chr>      <dbl>     <dbl>        <dbl>     <dbl>    <dbl>  <int>
1 EWR          -25      15.1           -1      1126     41.3 120835
2 JFK          -43      12.1           -1      1301     39.0 111279
3 LGA          -33      10.3           -3       911     40.0 104662

summarize()

Também é possível agrupar por mais de uma variável. Neste caso, serão criados grupos para cada cruzamento possível entre os níveis de cada grupo. Vamos verificar as estatísticas de atraso por origem e por mês. Como são 3 origens e 12 meses, teremos um data.frame de 36 linhas.

#Estatísticas de atraso por origem e mês
flights %>% 
  group_by(origin, month) %>% 
  summarize(
    min_delay = min(dep_delay, na.rm = T),
    avg_delay = mean(dep_delay, na.rm = T),
    median_delay = median(dep_delay, na.rm = T),
    max_delay = max(dep_delay, na.rm = T),
    sd_delay = sd(dep_delay, na.rm = T),
    n = n(),
  )
# A tibble: 36 × 8
# Groups:   origin [3]
   origin month min_delay avg_delay median_delay max_delay sd_delay     n
   <chr>  <int>     <dbl>     <dbl>        <dbl>     <dbl>    <dbl> <int>
 1 EWR        1       -21     14.9             0      1126     40.8  9893
 2 EWR        2       -21     13.1            -1       786     37.2  9107
 3 EWR        3       -22     18.1             0       443     44.1 10420
 4 EWR        4       -21     17.4            -1       545     43.9 10531
 5 EWR        5       -20     15.4             0       878     39.0 10592
 6 EWR        6       -19     22.5             1       502     50.8 10175
 7 EWR        7       -18     22.0             1       653     49.5 10475
 8 EWR        8       -17     13.5            -1       424     37.6 10359
 9 EWR        9       -23      7.29           -3       486     35.0  9550
10 EWR       10       -25      8.64           -2       702     32.7 10104
# ℹ 26 more rows

summarize()

Outra possibilidade é a utilização da função across(). Suponha obter um quadro com todas as médias de variáveis de tempos, agrupadas por origem. É possível utilizar a referida função da seguinte forma:

flights %>% 
  group_by(origin) %>% 
  summarise(across(.cols = contains(c("time", "delay")),
            mean, na.rm = T, .names = "average_{.col}")) %>% 
  select(-average_time_hour)
# A tibble: 3 × 8
  origin average_dep_time average_sched_dep_time average_arr_time
  <chr>             <dbl>                  <dbl>            <dbl>
1 EWR               1337.                  1322.            1492.
2 JFK               1399.                  1402.            1520.
3 LGA               1310.                  1308.            1494.
# ℹ 4 more variables: average_sched_arr_time <dbl>, average_air_time <dbl>,
#   average_dep_delay <dbl>, average_arr_delay <dbl>

Aqui cabem duas observações:

  • retiramos a variável average_time_hour, pois ela não faz sentido dentro da proposta e foi incluída pela seleção do tipo contains();

  • Podemos repassar parâmetros das funções utilizadas para a função across por meio da adição dos referidos parâmetros após a função. Em nosso exemplo, solicitamos a remoção dos dados faltantes no cálculo da média.

Chaining

Muitas vezes é necessária a criação de novas variáveis baseadas em variáveis recém criadas, que não pertencem ao banco de dados. No pacote dplyr, o recurso denominado chaining, ou encadeamento, em português é usado.

Esse encadeamento consiste na criação de uma nova variável que tem como base uma variável criada anteriormente, utilizando, funções como summarise, mutate e across.

Chaining

Para ilustrar, suponha desejar uma tabela de frequências de voos por origem, com frequências absolutas e relativas. A frequência relativa depende da absoluta, que não existe no banco de dados. Veja como proceder em casos deste tipo:

flights %>% 
  group_by(origin) %>% 
  summarise(freq_abs = n()) %>% 
  mutate(freq_rel = freq_abs/sum(freq_abs)) %>% 
  mutate(freq_per = paste0(round(100*freq_rel, 2), "%"))
# A tibble: 3 × 4
  origin freq_abs freq_rel freq_per
  <chr>     <int>    <dbl> <chr>   
1 EWR      120835    0.359 35.88%  
2 JFK      111279    0.330 33.04%  
3 LGA      104662    0.311 31.08%  

Chaining

Utilizamos a variável frequencia absoluta para criar a variável frequência relativa e utilizamos a variável frequência relativa para criar a variável frequência percentual. A rigor, as operações de encadeamento são operações de transformação comuns, aplicadas ao novo objeto criado.

É importante destacar que a função sumarise() funciona mesmo se nenhum grupo for definido. Neste caso, ela interpreta a existência de apenas um grupo e fornece as estatísticas para todos os dados.

Funções slice

É possível selecionar determinadas linhas dentre as presentes em um agrupamento ou mesmo em um conjunto de dados completo. Para tal, utiliza-se as funções da família slice. São cinco principais funções:

  • data.frame %>% slice_head(n = 1) retorna a primeira linha de cada grupo.

  • data.frame %>% slice_tail(n = 1) retorna a última linha de cada grupo..

  • data.frame %>% slice_min(x, n = 1) retorna a linha com o menor valor da coluna x.

  • data.frame %>% slice_max(x, n = 1) retorna a linha com o maior valor da coluna x.

  • data.frame %>% slice_sample(n = k) retorna k linhas aleatórias.

Note que, variando o parâmetro n, é possível selecionar quantas linhas forem necessárias. Pode-se, por exemplo, utilizar a função slice_sample() para definir grupos de treinamento e teste em um modelo de aprendizado estatístico.

Funções slice

Veja alguns exemplos do uso das funções.

#Dois maiores tempo de voo por origem
flights %>% 
  group_by(origin) %>% 
  slice_max(air_time, n = 2) %>% 
  relocate(origin, air_time)
# A tibble: 7 × 19
# Groups:   origin [3]
  origin air_time  year month   day dep_time sched_dep_time dep_delay arr_time
  <chr>     <dbl> <int> <int> <int>    <int>          <int>     <dbl>    <int>
1 EWR         695  2013     3    17     1337           1335         2     1937
2 EWR         676  2013    11    12      936            930         6     1630
3 JFK         691  2013     2     6      853            900        -7     1542
4 JFK         686  2013     3    15     1001           1000         1     1551
5 JFK         686  2013     3    17     1006           1000         6     1607
6 LGA         331  2013     9    10     1513           1507         6     1914
7 LGA         300  2013     9    14     1451           1500        -9     1810
# ℹ 10 more variables: sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
#   flight <int>, tailnum <chr>, dest <chr>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

Note que, ao solicitarmos os dois maiores tempos de voo por origem, foram retornados 7 resultados, e não 6, conforme era esperado. Isto ocorre porque a função mantém os empates.

Funções slice

#Menores atrasos por destino
flights %>% 
  group_by(dest) %>% 
  slice_max(arr_delay, n = 1) %>% 
  relocate(dest, arr_delay)
# A tibble: 108 × 19
# Groups:   dest [105]
   dest  arr_delay  year month   day dep_time sched_dep_time dep_delay arr_time
   <chr>     <dbl> <int> <int> <int>    <int>          <int>     <dbl>    <int>
 1 ABQ         153  2013     7    22     2145           2007        98      132
 2 ACK         221  2013     7    23     1139            800       219     1250
 3 ALB         328  2013     1    25      123           2000       323      229
 4 ANC          39  2013     8    17     1740           1625        75     2042
 5 ATL         895  2013     7    22     2257            759       898      121
 6 AUS         349  2013     7    10     2056           1505       351     2347
 7 AVL         228  2013     8    13     1156            832       204     1417
 8 BDL         266  2013     2    21     1728           1316       252     1839
 9 BGR         238  2013    12     1     1504           1056       248     1628
10 BHM         291  2013     4    10       25           1900       325      136
# ℹ 98 more rows
# ℹ 10 more variables: sched_arr_time <int>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

Funções slice

#Amostra das datas de voo por origem, 10 por origem
flights %>% 
  group_by(origin) %>% 
  slice_sample(n = 10)
# A tibble: 30 × 19
# Groups:   origin [3]
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013    12    27      741            739         2     1236           1238
 2  2013    12    23     1024           1010        14     1254           1226
 3  2013    12    13     1453           1459        -6     1645           1654
 4  2013     7     5     1546           1553        -7     1744           1755
 5  2013     2    20      826            835        -9     1106           1134
 6  2013     1    29     2033           1935        58        5           2207
 7  2013     3    26      513            515        -2      747            814
 8  2013     3     5     2106           2100         6     2237           2228
 9  2013    10    30      849            852        -3     1201           1208
10  2013    12    13     1622           1625        -3     1807           1755
# ℹ 20 more rows
# ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

Joins

Usualmente uma análise de dados ou um projeto de ciência de dados envolve mais de um conjunto de dados. É comum a necessidade de agregação de informações de fontes distintas. Essas agregações geralmente são utilizadas pelo uso das funções do tipo join. O papel das funções join é agregar informações de dois bancos de dados por meio de uma chave, comum a ambas as variáveis.

Joins

Suponha dois conjuntos de dados, x e y:

  • inner_join(x, y): Mantém apenas as observações de x que tem correspondentes em y;

  • outer joins: Mantém informações que aparecem em pelo menos um dos bancos de dados. São elas:

    • left_join(x, y): Mantém todas as observações de x e agrega as informações disponíveis em y;

    • right_join(x, y) : Mantém todas as observações de y e agrega as informações disponíveis em x;

    • full_join(x, y): Mantém todas as observações de x e y e agrega as informações disponíveis em ambos;

Joins

Para exemplificar, será utilizado o conjunto de dados planes, que oferece a informação dos aviões, juntamente com o conjunto flights. Inicialmente fazer o join sem especificar as variáveis de agregação.

#Variáveis comuns aos conjuntos de dados
intersect(names(planes), names(flights))
[1] "tailnum" "year"   
#União dos bancos de dados usando left_join
left_join(flights, planes)
# A tibble: 336,776 × 26
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1  2013     1     1      517            515         2      830            819
 2  2013     1     1      533            529         4      850            830
 3  2013     1     1      542            540         2      923            850
 4  2013     1     1      544            545        -1     1004           1022
 5  2013     1     1      554            600        -6      812            837
 6  2013     1     1      554            558        -4      740            728
 7  2013     1     1      555            600        -5      913            854
 8  2013     1     1      557            600        -3      709            723
 9  2013     1     1      557            600        -3      838            846
10  2013     1     1      558            600        -2      753            745
# ℹ 336,766 more rows
# ℹ 18 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, type <chr>, manufacturer <chr>,
#   model <chr>, engines <int>, seats <int>, speed <int>, engine <chr>

Foram geradas colunas de dados faltantes, isso ocorreu porque ao não se especificar a variável de agregação, a função efetuou a agregação por número de cauda e ano. Entretanto, a variável year representa informações diferentes em cada banco de dados. Por esse motivo, não há correspondência exata.

Joins

A agregação será agora efetuada definindo a variável tailnum como base para a fusão, por meio do parâmetro by.

left_join(flights, planes, by = "tailnum")
# A tibble: 336,776 × 27
   year.x month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1   2013     1     1      517            515         2      830            819
 2   2013     1     1      533            529         4      850            830
 3   2013     1     1      542            540         2      923            850
 4   2013     1     1      544            545        -1     1004           1022
 5   2013     1     1      554            600        -6      812            837
 6   2013     1     1      554            558        -4      740            728
 7   2013     1     1      555            600        -5      913            854
 8   2013     1     1      557            600        -3      709            723
 9   2013     1     1      557            600        -3      838            846
10   2013     1     1      558            600        -2      753            745
# ℹ 336,766 more rows
# ℹ 19 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, year.y <int>, type <chr>,
#   manufacturer <chr>, model <chr>, engines <int>, seats <int>, speed <int>,
#   engine <chr>

Note que agora as informações foram agregadas corretamente.

Joins

Aplicações de outros tipos tipos de join.

#inner_join
inner_join(flights, planes, by = "tailnum")
# A tibble: 284,170 × 27
   year.x month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1   2013     1     1      517            515         2      830            819
 2   2013     1     1      533            529         4      850            830
 3   2013     1     1      542            540         2      923            850
 4   2013     1     1      544            545        -1     1004           1022
 5   2013     1     1      554            600        -6      812            837
 6   2013     1     1      554            558        -4      740            728
 7   2013     1     1      555            600        -5      913            854
 8   2013     1     1      557            600        -3      709            723
 9   2013     1     1      557            600        -3      838            846
10   2013     1     1      558            600        -2      849            851
# ℹ 284,160 more rows
# ℹ 19 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, year.y <int>, type <chr>,
#   manufacturer <chr>, model <chr>, engines <int>, seats <int>, speed <int>,
#   engine <chr>

Joins

Aplicações de outros tipos tipos de join.

#right_join
right_join(flights, planes, by = "tailnum")
# A tibble: 284,170 × 27
   year.x month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1   2013     1     1      517            515         2      830            819
 2   2013     1     1      533            529         4      850            830
 3   2013     1     1      542            540         2      923            850
 4   2013     1     1      544            545        -1     1004           1022
 5   2013     1     1      554            600        -6      812            837
 6   2013     1     1      554            558        -4      740            728
 7   2013     1     1      555            600        -5      913            854
 8   2013     1     1      557            600        -3      709            723
 9   2013     1     1      557            600        -3      838            846
10   2013     1     1      558            600        -2      849            851
# ℹ 284,160 more rows
# ℹ 19 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, year.y <int>, type <chr>,
#   manufacturer <chr>, model <chr>, engines <int>, seats <int>, speed <int>,
#   engine <chr>

Joins

Aplicações de outros tipos tipos de join.

#full_join
full_join(flights, planes, by = "tailnum")
# A tibble: 336,776 × 27
   year.x month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
 1   2013     1     1      517            515         2      830            819
 2   2013     1     1      533            529         4      850            830
 3   2013     1     1      542            540         2      923            850
 4   2013     1     1      544            545        -1     1004           1022
 5   2013     1     1      554            600        -6      812            837
 6   2013     1     1      554            558        -4      740            728
 7   2013     1     1      555            600        -5      913            854
 8   2013     1     1      557            600        -3      709            723
 9   2013     1     1      557            600        -3      838            846
10   2013     1     1      558            600        -2      753            745
# ℹ 336,766 more rows
# ℹ 19 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>, year.y <int>, type <chr>,
#   manufacturer <chr>, model <chr>, engines <int>, seats <int>, speed <int>,
#   engine <chr>

Joins

As funções inner_join e right_join apresentam os mesmos resultados, assim como as funções left_join e full_join. Isso ocorre porque a única fonte de dados faltantes provém do conjunto de dados flights. Entretanto, quando esse não for o caso, esperaríamos quatro tabelas diferentes.

Existe uma grande quantidade de outras funções extremamente relevantes no pacote dplyr para manipulação de dados. Entretanto, as principais foram apresentadas. Para conhecer melhor as demais funções, bem como para obter dicas de uso, é possível utilizar o link a seguir: