Kapitel 3 Datamanipulering med dplyr

Det sägs ofta att en Data Scientist ägnar 80% av sin tid till att manipulera data så att den går att visualisera och modellera. Därför är det klokt att välja en metod och ett paket som underlättar det arbetet för dig.

I den här introduktionen kommer vi att fokusera på att använda paketet dplyr för att göra datamanipuleringar. dplyr är ett av de mest populära paketen i R och ger dig en bred verktygslåda för att manipulera data. dplyr ingår också i ett samlingspaket tidyverse och samlar flertalet paket för datamanipulering, visualisering och modellering.

dplyr har ett antal verb för att göra manipuleringar:

  • filter() där du väljer observationer baserat på deras värden
  • arrange() som ändrar ordningen på rader
  • select() för att välja variabler baserat på deras namn
  • mutate() för att skapa nya variabler baserat på funktioner
  • summarise() för att summera många värden till ett värde

Samtliga av dessa verb kan användas i kombination med funktionen group_by() som innebär att du utför verben på flera grupper.

Alla verb i dplyr är konsekventa. Det första argumentet är din data och i det andra argumentet specificerar du vad du vill göra med din data. Resultatet är alltid en ny data.frame.

3.1 Filter

Med filter kan du enkelt filtrera din data baserat på villkor.

Dessa villkor uttrycks med hjälp av relationsoperatorer och logical operators.

I R är dessa:

Relationsoperator Symbol i R
och (and) &
eller(or) |
icke(not) !
Logical Operators Symbol i R
lika ==
inte lika !=
större än eller lika >=
mindre än eller lika <=
större än >
mindre än <
finns i %in%

Dessa kan du använda i filter().

PS: Det vanligaste misstaget i början av din R-karriär är att skriva = istället för ==.

Så här använder du operatorerna:

Hitta alla flyg som kom fram 08:30 under februari

library(dplyr)
library(nycflights13)
filter(flights, month == 2, arr_time == 830)
## # A tibble: 9 x 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     2     2      656            700        -4      830            839
## 2  2013     2     4      652            600        52      830            759
## 3  2013     2     6      629            630        -1      830            845
## 4  2013     2    13      633            636        -3      830            808
## 5  2013     2    18      717            700        17      830            832
## 6  2013     2    24      557            600        -3      830            837
## 7  2013     2    25      532            540        -8      830            850
## 8  2013     2    26      615            615         0      830            820
## 9  2013     2    28      621            630        -9      830            830
## # … with 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>

Hitta alla flygbolag som finns i c("UA", "DL") i februari eller mars och som inte var försenade.

filter(flights, carrier %in% c("UA", "DL"), month == 2 | month == 3, dep_delay <= 0)
## # A tibble: 10,346 x 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     2     1      520            525        -5      816            820
##  2  2013     2     1      527            530        -3      837            829
##  3  2013     2     1      554            601        -7      920            918
##  4  2013     2     1      558            600        -2      738            759
##  5  2013     2     1      559            600        -1      923            925
##  6  2013     2     1      600            600         0      833            837
##  7  2013     2     1      601            608        -7      703            725
##  8  2013     2     1      601            608        -7      723            755
##  9  2013     2     1      604            610        -6      752            817
## 10  2013     2     1      608            615        -7      837            842
## # … with 10,336 more rows, and 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>

3.1.1 Övning

Hur många plan…

  1. var försenade mer än 1 timme?
  2. skulle till Boston (“BOS”)
  3. lämnade JFK och var försenade
  4. lämnade JFK på julafton
  5. var försenade, men inte kom fram försent
  6. flög United Airlines (UA) eller American Airlines?

3.2 Arrange

arrange() kastar om ordningen på dina rader enligt en av dig vald variabel. Exempelvis kanske vi vill sortera data på försenade avgångar dep_delay.

arrange(flights, dep_delay)
## # A tibble: 336,776 x 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    12     7     2040           2123       -43       40           2352
##  2  2013     2     3     2022           2055       -33     2240           2338
##  3  2013    11    10     1408           1440       -32     1549           1559
##  4  2013     1    11     1900           1930       -30     2233           2243
##  5  2013     1    29     1703           1730       -27     1947           1957
##  6  2013     8     9      729            755       -26     1002            955
##  7  2013    10    23     1907           1932       -25     2143           2143
##  8  2013     3    30     2030           2055       -25     2213           2250
##  9  2013     3     2     1431           1455       -24     1601           1631
## 10  2013     5     5      934            958       -24     1225           1309
## # … with 336,766 more rows, and 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() sorterar per default på sjunkande värde (ascending). Vill du sortera på stigande värde (descending) sätter du desc() runt din variabel.

arrange(flights, desc(dep_delay))
## # A tibble: 336,776 x 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
## # … with 336,766 more rows, and 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>

3.2.1 Övning

Hitta det flyg som…

  1. flög längst
  2. var mest försenat (när det kom fram)

3.3 Select

Medan arrange() kastar om raderna så kastar select() om kolumnerna. Men mest används den för att välja ut kolumner av intresse.

select(flights, dep_delay, carrier)
## # A tibble: 336,776 x 2
##    dep_delay carrier
##        <dbl> <chr>  
##  1         2 UA     
##  2         4 UA     
##  3         2 AA     
##  4        -1 B6     
##  5        -6 DL     
##  6        -4 UA     
##  7        -5 B6     
##  8        -3 EV     
##  9        -3 B6     
## 10        -2 AA     
## # … with 336,766 more rows

Om du av något skäl vill flytta en kolumn till början kan du skriva:

select(flights, carrier, everything())
## # A tibble: 336,776 x 19
##    carrier  year month   day dep_time sched_dep_time dep_delay arr_time
##    <chr>   <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1 UA       2013     1     1      517            515         2      830
##  2 UA       2013     1     1      533            529         4      850
##  3 AA       2013     1     1      542            540         2      923
##  4 B6       2013     1     1      544            545        -1     1004
##  5 DL       2013     1     1      554            600        -6      812
##  6 UA       2013     1     1      554            558        -4      740
##  7 B6       2013     1     1      555            600        -5      913
##  8 EV       2013     1     1      557            600        -3      709
##  9 B6       2013     1     1      557            600        -3      838
## 10 AA       2013     1     1      558            600        -2      753
## # … with 336,766 more rows, and 11 more variables: sched_arr_time <int>,
## #   arr_delay <dbl>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

Du kan även välja alla kolumner mellan två kolumner:

select(flights, year:day)
## # A tibble: 336,776 x 3
##     year month   day
##    <int> <int> <int>
##  1  2013     1     1
##  2  2013     1     1
##  3  2013     1     1
##  4  2013     1     1
##  5  2013     1     1
##  6  2013     1     1
##  7  2013     1     1
##  8  2013     1     1
##  9  2013     1     1
## 10  2013     1     1
## # … with 336,766 more rows

Genom att sätta ett minus framför variabelnamnet exkluderar du variabeln.

select(flights, -year)
## # A tibble: 336,776 x 18
##    month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1     1     1      517            515         2      830            819
##  2     1     1      533            529         4      850            830
##  3     1     1      542            540         2      923            850
##  4     1     1      544            545        -1     1004           1022
##  5     1     1      554            600        -6      812            837
##  6     1     1      554            558        -4      740            728
##  7     1     1      555            600        -5      913            854
##  8     1     1      557            600        -3      709            723
##  9     1     1      557            600        -3      838            846
## 10     1     1      558            600        -2      753            745
## # … with 336,766 more rows, and 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>

3.3.0.1 select() plus hjälpfunktioner

select() kommer med ett antal hjälpfunktioner:

  • starts_with("asd")
  • ends_with("air")
  • contains("flyg")
  • matches("asd")
  • num_range("flyg", 1:10)

De används för att identifiera kolumner baserat på text.

Exempelvis kan du hitta alla delay-kolumner med contains.

select(flights, contains("delay"))
## # A tibble: 336,776 x 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
## # … with 336,766 more rows

3.3.0.2 rename()

En annan nyttig funktion är rename() som kort och gott döper om variabler.

Formeln är rename(data, ny_variabel = gammal_variabel)

3.3.1 Övning

  1. Som innehåller “dep”
  2. Som börjar med “dep”
  3. Döp om dep_delay till försenad_avgång

3.4 Mutate

mutate() används för att skapa nya variabler.

Exempelvis kan vi räkna ut hur mycket tid man vunnit om exempelvis flyget landar tidigare än avsett.

mutate(flights, beer_time = dep_delay - arr_delay)
## # A tibble: 336,776 x 20
##     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
## # … with 336,766 more rows, and 12 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>,
## #   beer_time <dbl>

I mutate() kan du även använda funktioner såsom mean().

mutate(flights, mean_delay = mean(dep_delay, na.rm = T))
## # A tibble: 336,776 x 20
##     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
## # … with 336,766 more rows, and 12 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>,
## #   mean_delay <dbl>

3.4.1 if_else()

En vanlig funktion i databearbetning är ifelse-satser.

I R gör du det enklast med funktionen if_else() från dplyr. Det finns även en inbyggd funktion som heter ifelse() som mestadels fungerar bra men den från dplyr är något mer stabil.

Du kan använda den i mutate:

mutate(flights, försenad = if_else(dep_delay  > 5, "försenad", "ej försenad"))
## # A tibble: 336,776 x 20
##     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
## # … with 336,766 more rows, and 12 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>,
## #   försenad <chr>

Ibland vill man göra flera stycken if_else() i samma, exempelvis om man vill dela upp en variabel i flera kategorier beroende på ett logiskt villkor. För att göra det kan du använda funktionen case_when().

mutate(flights, försenad_kat = case_when(
dep_delay < 0 ~ "före tid",
dep_delay == 0 ~ "i tid",
dep_delay > 0 ~ "försenad")) 
## # A tibble: 336,776 x 20
##     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
## # … with 336,766 more rows, and 12 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>,
## #   försenad_kat <chr>

3.4.2 Andra funktioner

I mutate() kan du använda de allra flesta funktionerna i R. Här är exempel på några funktioner som kan vara nyttiga i databearbetning:

  • Funktioner för att ranka variabler: rank(), min_rank(), dense_rank(), percent_rank()
  • För att logaritmiska funktioner: log(), log10()
  • För kumulativa beräkningar: cumsum(), cummean()
  • För att bara generera radnummer: row_number()
  • För att ta observation innan eller efter: lead() och lag()
  • För skapa variabler baserat på värde i andra variabler if_else() och case_when()

3.4.3 Övningar

  1. Skapa en variabel som innehåller den totala förseningen
  2. Rangordna flygens distans. Hur hanterar du fall där distansen är lika lång?
  3. Skapa en variabel som anger om flyget går på våren, hösten, vintern eller sommaren.

3.5 Summarise

Ofta vill man summera variabler för att få ut intressant information. Exempelvis vill vi här kanske veta en rad medelvärden.

summarise(flights, mean_dist = mean(distance, na.rm = T))
## # A tibble: 1 x 1
##   mean_dist
##       <dbl>
## 1     1040.
summarise(flights, sum_dist = sum(distance, na.rm = T))
## # A tibble: 1 x 1
##    sum_dist
##       <dbl>
## 1 350217607
summarise(flights, count = n())
## # A tibble: 1 x 1
##    count
##    <int>
## 1 336776

Men dessa värden är inte så intressanta i sig, utan vi vill kunna göra jämförelse. Då använder vi group_by().

group_by_flights <- group_by(flights, carrier)

summarise(group_by_flights, 
          mean_air_time = mean(air_time, na.rm = T),
          mean_dep_delay = mean(dep_delay, na.rm = T),
          mean_arr_delay = mean(arr_delay, na.rm = T))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 16 x 4
##    carrier mean_air_time mean_dep_delay mean_arr_delay
##    <chr>           <dbl>          <dbl>          <dbl>
##  1 9E               86.8          16.7           7.38 
##  2 AA              189.            8.59          0.364
##  3 AS              326.            5.80         -9.93 
##  4 B6              151.           13.0           9.46 
##  5 DL              174.            9.26          1.64 
##  6 EV               90.1          20.0          15.8  
##  7 F9              230.           20.2          21.9  
##  8 FL              101.           18.7          20.1  
##  9 HA              623.            4.90         -6.92 
## 10 MQ               91.2          10.6          10.8  
## 11 OO               83.5          12.6          11.9  
## 12 UA              212.           12.1           3.56 
## 13 US               88.6           3.78          2.13 
## 14 VX              337.           12.9           1.76 
## 15 WN              148.           17.7           9.65 
## 16 YV               65.7          19.0          15.6

I summarise() kan du använda en rad olika funktioner såsom sum() för summeringar, median() etc.

3.5.0.1 Övningar

  1. Vilken flygplats har högst medelvärde förförseningar från flygplatsen?
  2. Vilken flygplats tar emot minst flyg?

3.5.0.2 Väv ihop verben med %>%

Med %>% (som kallas för pipe and kan uttalas som and then) kan länka ihop flera uttryck i R. Det gör framför allt din kod mer lättläst.

Med %>% kan du exempelvis först filtrera, sen gruppera och till sist summera, allt i samma uttryck.

flights %>%
filter(dep_delay < 60) %>%
group_by(carrier) %>%
summarise(mean_dep_delay = mean(dep_delay, na.rm = T))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 16 x 2
##    carrier mean_dep_delay
##    <chr>            <dbl>
##  1 9E               2.96 
##  2 AA               0.890
##  3 AS              -0.719
##  4 B6               3.26 
##  5 DL               1.76 
##  6 EV               4.65 
##  7 F9               5.09 
##  8 FL               4.72 
##  9 HA              -2.47 
## 10 MQ               1.48 
## 11 OO              -2.88 
## 12 UA               4.33 
## 13 US              -0.744
## 14 VX               2.70 
## 15 WN               6.60 
## 16 YV               2.25

Du läser alltså: Första tar vi flights and then filtrerar vi på dep_delay and then grupperar vi på carrier and then räknar vi ut medelvärde på dep_delay.

Vilket är mycket mer lättläst än motsvarigheten med parenteser:

summarise(
  group_by(
    filter(flights, dep_delay > 60),
    carrier),
  mean_dep_delay = mean(dep_delay, na.rm = T))

3.5.0.3 count()

Du kan i summarise() räkna antalet observationer med funktionen n().

flights %>%
  group_by(carrier) %>%
  summarise(count = n())
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 16 x 2
##    carrier count
##    <chr>   <int>
##  1 9E      18460
##  2 AA      32729
##  3 AS        714
##  4 B6      54635
##  5 DL      48110
##  6 EV      54173
##  7 F9        685
##  8 FL       3260
##  9 HA        342
## 10 MQ      26397
## 11 OO         32
## 12 UA      58665
## 13 US      20536
## 14 VX       5162
## 15 WN      12275
## 16 YV        601

Men istället för att göra det här kan du använda funktionen count()

flights %>%
  group_by(carrier) %>%
  count()
## # A tibble: 16 x 2
## # Groups:   carrier [16]
##    carrier     n
##    <chr>   <int>
##  1 9E      18460
##  2 AA      32729
##  3 AS        714
##  4 B6      54635
##  5 DL      48110
##  6 EV      54173
##  7 F9        685
##  8 FL       3260
##  9 HA        342
## 10 MQ      26397
## 11 OO         32
## 12 UA      58665
## 13 US      20536
## 14 VX       5162
## 15 WN      12275
## 16 YV        601

3.6 sample_n()

Att göra slumpmässiga urval är en vanlig arbetsuppgift för en data scientist. Det gör du enkelt med sample_n() från dplyr.

Om du vill ta ett slumpmässigt urval om 10 från exempelvis flights gör du bara:

sample_n(flights, 10)
## # A tibble: 10 x 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     4    15     1403           1348        15     1631           1636
##  2  2013    11     6     1046           1049        -3     1233           1239
##  3  2013    11    26     1254           1300        -6     1430           1428
##  4  2013    11     1     1026           1030        -4     1249           1252
##  5  2013    12    11     2152           2159        -7        1           2359
##  6  2013    10    10      857            900        -3     1145           1144
##  7  2013     7    17      921            915         6     1154           1215
##  8  2013     7    27      629            630        -1      832            835
##  9  2013     9     6     1734           1735        -1     1935           1944
## 10  2013     6    15     1301           1309        -8     1411           1424
## # … with 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>

Om du istället vill ta ett urval som baseras på procent kan du använda sample_frac, här för 0.01%

sample_frac(flights, 0.001)
## # A tibble: 337 x 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    17     1140           1145        -5     1311           1320
##  2  2013    12    31     1310           1215        55     1545           1445
##  3  2013    12     8     1515           1525       -10     1738           1720
##  4  2013    12     8     1905           1807        58     2314           1950
##  5  2013    12     3     1453           1454        -1     1937           1951
##  6  2013     9    17      809            815        -6     1052           1121
##  7  2013     9    30      806            815        -9     1019           1040
##  8  2013     8     7      917            849        28     1139           1115
##  9  2013    10    25      558            600        -2      904            858
## 10  2013    10    27     1056           1100        -4     1247           1300
## # … with 327 more rows, and 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>

3.6.1 Övning

  1. Vilken månad ska du flyga under för att undvika förseningar?
  2. Vilken tid ska du flyga för att undvika förseningar?
  3. Hitta det flygbolag som flyger till flest destinationer, rangordna flygbolagen baserat på den informationen.