1 Balíčky a načtení dat

Nainstalujte si balíček nycflights13, jinak samozřejmě nepůjde načíst pomocí funkce library().

library(nycflights13)
library(tidyverse)
library(haven)

Jako cvičná data použijeme dataset z balíčku nycflights13. Obsahuje údaje o všech odletech ze tří velkých letišť v New Yourku. Protože obsahuje velké množství pozorování, nahádně si z něj vybereme 1000 pozorování, aby práce s daty byla rychlejší. Podívejte se na nápovědu k datasetu pomocí ?flightsa na přehled dat pomocí funkcí summary() a glimse() nebo str().

set.seed(123)
flights <- slice_sample(flights, n = 1e4)

?flights
#> starting httpd help server ... done
summary(flights)
#>       year          month             day           dep_time    sched_dep_time
#>  Min.   :2013   Min.   : 1.000   Min.   : 1.00   Min.   :   1   Min.   : 500  
#>  1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00   1st Qu.: 857   1st Qu.: 900  
#>  Median :2013   Median : 7.000   Median :16.00   Median :1356   Median :1355  
#>  Mean   :2013   Mean   : 6.541   Mean   :15.78   Mean   :1338   Mean   :1332  
#>  3rd Qu.:2013   3rd Qu.:10.000   3rd Qu.:23.00   3rd Qu.:1732   3rd Qu.:1720  
#>  Max.   :2013   Max.   :12.000   Max.   :31.00   Max.   :2400   Max.   :2359  
#>                                                  NA's   :237                  
#>    dep_delay          arr_time    sched_arr_time   arr_delay       
#>  Min.   : -22.00   Min.   :   1   Min.   :   1   Min.   : -70.000  
#>  1st Qu.:  -5.00   1st Qu.:1058   1st Qu.:1116   1st Qu.: -17.000  
#>  Median :  -2.00   Median :1534   Median :1554   Median :  -4.000  
#>  Mean   :  12.25   Mean   :1500   Mean   :1529   Mean   :   6.674  
#>  3rd Qu.:  10.00   3rd Qu.:1935   3rd Qu.:1935   3rd Qu.:  14.000  
#>  Max.   :1014.00   Max.   :2400   Max.   :2359   Max.   :1007.000  
#>  NA's   :237       NA's   :248                   NA's   :270       
#>    carrier              flight       tailnum             origin         
#>  Length:10000       Min.   :   1   Length:10000       Length:10000      
#>  Class :character   1st Qu.: 561   Class :character   Class :character  
#>  Mode  :character   Median :1485   Mode  :character   Mode  :character  
#>                     Mean   :1961                                        
#>                     3rd Qu.:3416                                        
#>                     Max.   :6181                                        
#>                                                                         
#>      dest              air_time        distance         hour      
#>  Length:10000       Min.   : 24.0   Min.   :  94   Min.   : 5.00  
#>  Class :character   1st Qu.: 84.0   1st Qu.: 509   1st Qu.: 9.00  
#>  Mode  :character   Median :131.0   Median : 888   Median :13.00  
#>                     Mean   :152.2   Mean   :1049   Mean   :13.06  
#>                     3rd Qu.:193.0   3rd Qu.:1389   3rd Qu.:17.00  
#>                     Max.   :661.0   Max.   :4983   Max.   :23.00  
#>                     NA's   :270                                   
#>      minute        time_hour                  
#>  Min.   : 0.00   Min.   :2013-01-01 06:00:00  
#>  1st Qu.: 7.00   1st Qu.:2013-04-03 13:00:00  
#>  Median :29.00   Median :2013-07-03 07:00:00  
#>  Mean   :26.26   Mean   :2013-07-03 01:37:30  
#>  3rd Qu.:45.00   3rd Qu.:2013-10-01 18:15:00  
#>  Max.   :59.00   Max.   :2013-12-31 21:00:00  
#> 

glimpse(flights)
#> Rows: 10,000
#> Columns: 19
#> $ year           <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2…
#> $ month          <int> 4, 2, 2, 3, 6, 2, 5, 10, 11, 8, 11, 4, 3, 7, 12, 10, 6,…
#> $ day            <int> 26, 26, 15, 27, 5, 16, 1, 20, 11, 31, 4, 19, 10, 29, 7,…
#> $ dep_time       <int> 730, 1714, 1442, 1444, 1428, 613, 848, 1918, 825, 656, …
#> $ sched_dep_time <int> 655, 1720, 1445, 1445, 1430, 600, 850, 1855, 835, 700, …
#> $ dep_delay      <dbl> 35, -6, -3, -1, -2, 13, -2, 23, -10, -4, 6, NA, 7, -9, …
#> $ arr_time       <int> 901, 2031, 1634, 1556, 1537, 731, 947, 2132, 942, 904, …
#> $ sched_arr_time <int> 820, 2040, 1647, 1604, 1555, 735, 1014, 2130, 1000, 929…
#> $ arr_delay      <dbl> 41, -9, -13, -8, -18, -4, -27, 2, -18, -25, 10, NA, -13…
#> $ carrier        <chr> "WN", "AA", "US", "9E", "EV", "MQ", "9E", "DL", "MQ", "…
#> $ flight         <int> 404, 1999, 1445, 3452, 5699, 3768, 3465, 87, 3355, 1547…
#> $ tailnum        <chr> "N7735A", "N625AA", "N557UW", "N921XJ", "N830AS", "N546…
#> $ origin         <chr> "LGA", "EWR", "LGA", "JFK", "LGA", "EWR", "JFK", "JFK",…
#> $ dest           <chr> "MKE", "MIA", "CLT", "BOS", "IAD", "ORD", "BOS", "ATL",…
#> $ air_time       <dbl> 116, 178, 92, 44, 44, 113, 34, 112, 113, 107, 309, NA, …
#> $ distance       <dbl> 738, 1085, 544, 187, 229, 719, 187, 760, 764, 762, 2153…
#> $ hour           <dbl> 6, 17, 14, 14, 14, 6, 8, 18, 8, 7, 16, 17, 18, 13, 9, 1…
#> $ minute         <dbl> 55, 20, 45, 45, 30, 0, 50, 55, 35, 0, 30, 0, 55, 25, 45…
#> $ time_hour      <dttm> 2013-04-26 06:00:00, 2013-02-26 17:00:00, 2013-02-15 1…

2 Úvod

V této lekci probereme pět nejdůležitějších funkcí z balíčku dplyr, který je součástní tidyverse. Tyto funkce pokryjí většinu našich potřeb manipulace a tranformace dat. Jedná se o:

  • Výběr pozorování (řádků) pomocí funkce filter().
  • Seřazení řádků pmocí funkce arrange().
  • Výběr proměnný (sloupců) pomocí funkce select().
  • Tvorba nových proměnných pomocí funkce mutate().
  • A výpočet různých statistik pomocí funkce summarise().

Názvy těchto funkcí jsou tedy slovesa a odpovídají tomu, co daná funkce dělá. Všechny tyto funkce také fungují podobně:

  • Prvním argumentem je vždy použitý dataframe (tibble).
  • Další argumenty specifikují, co přesně má daná funkce udělat.
  • Na jména sloupců se můžeme odkazovat jednoduše jejich názvy a nemusíme je ani dávat do uvozovek.
  • Výstupem je vždy nový dataframe.

3 Výběr řádků pomocí funkce filter()

Funkce filter umožňuje výběr řádků na základě hodnot proměnných. První argumentem je použitý dataframe a dalšími argumenty jsou většinou logické podmínky určující, které řádky budou vybrány. Pokud tyto logické podmíny oddělujeme čárkami, říkáme, že musí platit všechny z nich, aby bylo dané pozorování (řádek) vybráno. Takto bychom vybrali lety, které odletěly prvního ledna.

# Výběr letů, které odletěly prvního ledna
filter(flights, month == 1, day == 1)
#> # A tibble: 19 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     1     1     1842       1422     260    1958    1535     263 EV     
#>  2  2013     1     1     1059       1053       6    1342    1351      -9 UA     
#>  3  2013     1     1      655        700      -5    1002    1020     -18 DL     
#>  4  2013     1     1     1128       1129      -1    1422    1437     -15 UA     
#>  5  2013     1     1     1453       1500      -7    1601    1620     -19 US     
#>  6  2013     1     1     1455       1500      -5    1753    1810     -17 DL     
#>  7  2013     1     1     1720       1725      -5    2121    2105      16 DL     
#>  8  2013     1     1     1740       1630      70    2102    1954      68 DL     
#>  9  2013     1     1     1910       1855      15    2118    2103      15 US     
#> 10  2013     1     1      628        630      -2    1016     947      29 UA     
#> 11  2013     1     1     1911       1910       1    2050    2055      -5 MQ     
#> 12  2013     1     1     1937       1905      32    2250    2225      25 AA     
#> 13  2013     1     1     1730       1730       0    2126    2110      16 B6     
#> 14  2013     1     1      914        900      14    1058    1043      15 UA     
#> 15  2013     1     1     1231       1229       2    1523    1529      -6 UA     
#> 16  2013     1     1     2026       2004      22    2157    2133      24 EV     
#> 17  2013     1     1     1959       2000      -1    2310    2307       3 UA     
#> 18  2013     1     1     1816       1805      11    2013    1955      18 MQ     
#> 19  2013     1     1     1400       1250      70    1645    1502     103 EV     
#> # … with 9 more variables: flight <int>, tailnum <chr>, origin <chr>,
#> #   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
#> #   time_hour <dttm>, and abbreviated variable names ¹​sched_dep_time,
#> #   ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

filter(flights, month == 1 & day == 1)
#> # A tibble: 19 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     1     1     1842       1422     260    1958    1535     263 EV     
#>  2  2013     1     1     1059       1053       6    1342    1351      -9 UA     
#>  3  2013     1     1      655        700      -5    1002    1020     -18 DL     
#>  4  2013     1     1     1128       1129      -1    1422    1437     -15 UA     
#>  5  2013     1     1     1453       1500      -7    1601    1620     -19 US     
#>  6  2013     1     1     1455       1500      -5    1753    1810     -17 DL     
#>  7  2013     1     1     1720       1725      -5    2121    2105      16 DL     
#>  8  2013     1     1     1740       1630      70    2102    1954      68 DL     
#>  9  2013     1     1     1910       1855      15    2118    2103      15 US     
#> 10  2013     1     1      628        630      -2    1016     947      29 UA     
#> 11  2013     1     1     1911       1910       1    2050    2055      -5 MQ     
#> 12  2013     1     1     1937       1905      32    2250    2225      25 AA     
#> 13  2013     1     1     1730       1730       0    2126    2110      16 B6     
#> 14  2013     1     1      914        900      14    1058    1043      15 UA     
#> 15  2013     1     1     1231       1229       2    1523    1529      -6 UA     
#> 16  2013     1     1     2026       2004      22    2157    2133      24 EV     
#> 17  2013     1     1     1959       2000      -1    2310    2307       3 UA     
#> 18  2013     1     1     1816       1805      11    2013    1955      18 MQ     
#> 19  2013     1     1     1400       1250      70    1645    1502     103 EV     
#> # … with 9 more variables: flight <int>, tailnum <chr>, origin <chr>,
#> #   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
#> #   time_hour <dttm>, and abbreviated variable names ¹​sched_dep_time,
#> #   ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

Pro srovnání můžeme uvést, jak by daná operace vypadal v base R, bez použití balíčku dplyr.

flights[flights$month == 1 & flights$day == 1, ]
#> # A tibble: 19 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     1     1     1842       1422     260    1958    1535     263 EV     
#>  2  2013     1     1     1059       1053       6    1342    1351      -9 UA     
#>  3  2013     1     1      655        700      -5    1002    1020     -18 DL     
#>  4  2013     1     1     1128       1129      -1    1422    1437     -15 UA     
#>  5  2013     1     1     1453       1500      -7    1601    1620     -19 US     
#>  6  2013     1     1     1455       1500      -5    1753    1810     -17 DL     
#>  7  2013     1     1     1720       1725      -5    2121    2105      16 DL     
#>  8  2013     1     1     1740       1630      70    2102    1954      68 DL     
#>  9  2013     1     1     1910       1855      15    2118    2103      15 US     
#> 10  2013     1     1      628        630      -2    1016     947      29 UA     
#> 11  2013     1     1     1911       1910       1    2050    2055      -5 MQ     
#> 12  2013     1     1     1937       1905      32    2250    2225      25 AA     
#> 13  2013     1     1     1730       1730       0    2126    2110      16 B6     
#> 14  2013     1     1      914        900      14    1058    1043      15 UA     
#> 15  2013     1     1     1231       1229       2    1523    1529      -6 UA     
#> 16  2013     1     1     2026       2004      22    2157    2133      24 EV     
#> 17  2013     1     1     1959       2000      -1    2310    2307       3 UA     
#> 18  2013     1     1     1816       1805      11    2013    1955      18 MQ     
#> 19  2013     1     1     1400       1250      70    1645    1502     103 EV     
#> # … with 9 more variables: flight <int>, tailnum <chr>, origin <chr>,
#> #   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
#> #   time_hour <dttm>, and abbreviated variable names ¹​sched_dep_time,
#> #   ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

subset(flights,  month == 1 & day == 1)
#> # A tibble: 19 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     1     1     1842       1422     260    1958    1535     263 EV     
#>  2  2013     1     1     1059       1053       6    1342    1351      -9 UA     
#>  3  2013     1     1      655        700      -5    1002    1020     -18 DL     
#>  4  2013     1     1     1128       1129      -1    1422    1437     -15 UA     
#>  5  2013     1     1     1453       1500      -7    1601    1620     -19 US     
#>  6  2013     1     1     1455       1500      -5    1753    1810     -17 DL     
#>  7  2013     1     1     1720       1725      -5    2121    2105      16 DL     
#>  8  2013     1     1     1740       1630      70    2102    1954      68 DL     
#>  9  2013     1     1     1910       1855      15    2118    2103      15 US     
#> 10  2013     1     1      628        630      -2    1016     947      29 UA     
#> 11  2013     1     1     1911       1910       1    2050    2055      -5 MQ     
#> 12  2013     1     1     1937       1905      32    2250    2225      25 AA     
#> 13  2013     1     1     1730       1730       0    2126    2110      16 B6     
#> 14  2013     1     1      914        900      14    1058    1043      15 UA     
#> 15  2013     1     1     1231       1229       2    1523    1529      -6 UA     
#> 16  2013     1     1     2026       2004      22    2157    2133      24 EV     
#> 17  2013     1     1     1959       2000      -1    2310    2307       3 UA     
#> 18  2013     1     1     1816       1805      11    2013    1955      18 MQ     
#> 19  2013     1     1     1400       1250      70    1645    1502     103 EV     
#> # … with 9 more variables: flight <int>, tailnum <chr>, origin <chr>,
#> #   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
#> #   time_hour <dttm>, and abbreviated variable names ¹​sched_dep_time,
#> #   ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

Funkce z balíčku dplyr nidky nemodifikují původní vstupní dataset, pokud jej explicitně nepřepíšeme, takže pokud si chceme uložit výsledek operace, musíme použít assignment operator (<-)

jan1 <- filter(flights, month == 1, day == 1)

jan1
#> # A tibble: 19 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     1     1     1842       1422     260    1958    1535     263 EV     
#>  2  2013     1     1     1059       1053       6    1342    1351      -9 UA     
#>  3  2013     1     1      655        700      -5    1002    1020     -18 DL     
#>  4  2013     1     1     1128       1129      -1    1422    1437     -15 UA     
#>  5  2013     1     1     1453       1500      -7    1601    1620     -19 US     
#>  6  2013     1     1     1455       1500      -5    1753    1810     -17 DL     
#>  7  2013     1     1     1720       1725      -5    2121    2105      16 DL     
#>  8  2013     1     1     1740       1630      70    2102    1954      68 DL     
#>  9  2013     1     1     1910       1855      15    2118    2103      15 US     
#> 10  2013     1     1      628        630      -2    1016     947      29 UA     
#> 11  2013     1     1     1911       1910       1    2050    2055      -5 MQ     
#> 12  2013     1     1     1937       1905      32    2250    2225      25 AA     
#> 13  2013     1     1     1730       1730       0    2126    2110      16 B6     
#> 14  2013     1     1      914        900      14    1058    1043      15 UA     
#> 15  2013     1     1     1231       1229       2    1523    1529      -6 UA     
#> 16  2013     1     1     2026       2004      22    2157    2133      24 EV     
#> 17  2013     1     1     1959       2000      -1    2310    2307       3 UA     
#> 18  2013     1     1     1816       1805      11    2013    1955      18 MQ     
#> 19  2013     1     1     1400       1250      70    1645    1502     103 EV     
#> # … with 9 more variables: flight <int>, tailnum <chr>, origin <chr>,
#> #   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
#> #   time_hour <dttm>, and abbreviated variable names ¹​sched_dep_time,
#> #   ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

Jak už jste si asi všimli, R se chová tak, že budťo uloží nový datový objekt do globálního prostředí (ale nezobrazí výstup do konzole), nebo zobrazí výstup do konzole, ale neuloží výstup funkce. Pokud chceme obojí, musíme operaci “uzávorkovat”.

(dec25 <- filter(flights, month == 12, day == 25))
#> # A tibble: 26 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013    12    25     1724       1730      -6    2042    2056     -14 DL     
#>  2  2013    12    25     2149       2155      -6    2328    2334      -6 B6     
#>  3  2013    12    25     1218       1230     -12    1450    1516     -26 B6     
#>  4  2013    12    25     1834       1830       4    2135    2141      -6 UA     
#>  5  2013    12    25      712        715      -3     957    1015     -18 UA     
#>  6  2013    12    25     1532       1530       2    1847    1859     -12 DL     
#>  7  2013    12    25     1313       1314      -1    1609    1629     -20 B6     
#>  8  2013    12    25     1036       1045      -9    1332    1407     -35 DL     
#>  9  2013    12    25     1509       1520     -11    1638    1700     -22 MQ     
#> 10  2013    12    25      601        600       1     855     905     -10 AA     
#> # … with 16 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> #   minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> #   ¹​sched_dep_time, ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

K efektivnímu použít funkce filter je obvykle zapotřebí znát základní logické operátory, které R používá:

  • < znamená menší než.
  • > znamená větší než.
  • <= znamená menší nebo rovno.
  • >= znamená větší nebo rovno.
  • == znamená rovno.
  • != znamená nerovno.

Pro kombinaci více podmínek můžeme použít tyto operátory:

  • x & y znamená x a zároveň y (jsou obě podmínky splněny?). Pokud podmínky ve funkci filter() oddělujeme čárkami, znamená to rovněž, že všechny musí být splněny, aby byl řádek vybrán, takže je to ekvivalentní tomuto operátoru.
  • x | y znamená x nebo y (je aspoň jedna z podmínek splněna?).
  • xor(x, y) znamená buď x, anebo y (splnění právě jedné z podmínek, ne obou).

3.0.1 Cvičení

Pokuste se pomocí funkce filter() vybrat lety, které:

  • měly zpoždění na odletu více než hodninu
  • měly zpoždění na příletu více než hodninu
  • měly zpoždění na odletu a zároveň na příletu více než půl hodiny
  • měly zpoždění na odletu anebo na příletu více než hodinu.
  • měly zpoždění na odletu více než půl hodiny, ale žádné na příletu.
  • neměly zpoždění na odletu, ale na příletu alespoň půlhodinové.
  • měly alespoň půlhodinové zpoždění buď jen na odletu, nebo jen na příletu.
  • byly vypraveny v posledních třech mesících v roce.
  • byly vypraveny v druhé polovině roku.

Pro poslední dvě úlohy zkuste uplatnit také funkce between() a %in%. Jejich fungování si můřeme ukázat na cvičném vektoru x:

x <- 1:12
x
#>  [1]  1  2  3  4  5  6  7  8  9 10 11 12

between(x, 1, 3)
#>  [1]  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

x %in% c(1, 5, 10)
#>  [1]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE

3.1 Chybějící hodnoty

Jak už bychom měli vědět, když chceme určit, zda je nějaká hodnota chybějící, používáme k tomu funkci is.na(), nikoli např. x == NA. Takto bycho tedy vybrali lety s chybějícími údaji o zpoždění při odletu (dep_dalay).

filter(flights, is.na(dep_delay))
#> # A tibble: 237 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     4    19       NA       1700      NA      NA    1835      NA MQ     
#>  2  2013    12     7       NA        945      NA      NA    1300      NA AA     
#>  3  2013     7    10       NA       2030      NA      NA    2202      NA 9E     
#>  4  2013     8     8       NA       2140      NA      NA    2310      NA MQ     
#>  5  2013     2     9       NA        830      NA      NA     951      NA EV     
#>  6  2013     2     9       NA        901      NA      NA    1201      NA UA     
#>  7  2013     5    21       NA       1800      NA      NA    1938      NA UA     
#>  8  2013    12     5       NA       1740      NA      NA    1956      NA EV     
#>  9  2013     5    23       NA       1829      NA      NA    2144      NA UA     
#> 10  2013     3     8       NA        920      NA      NA    1125      NA MQ     
#> # … with 227 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> #   minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> #   ¹​sched_dep_time, ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

Funkce filter() vybere pouze řádky, pro které daná podmínka platí (je TRUE), takže hodnoty FALSE a NA jsou vyřazeny. Pokud bychom chtěli chybějící hodnoty ponechat, musíme to udělat explicitně.

# Lety s chybějícím dep_delay 
# anebo s větším než 2hodinových zpožděním při odletu
filter(flights, is.na(dep_delay) | dep_delay > 120)
#> # A tibble: 517 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     4    19       NA       1700      NA      NA    1835      NA MQ     
#>  2  2013    12     7       NA        945      NA      NA    1300      NA AA     
#>  3  2013     8    28     1920       1528     232    2119    1737     222 EV     
#>  4  2013     7    10       NA       2030      NA      NA    2202      NA 9E     
#>  5  2013     8     8       NA       2140      NA      NA    2310      NA MQ     
#>  6  2013    11    22     2142       1729     253     143    2013     330 UA     
#>  7  2013     6    25     2120       1905     135    2310    2103     127 9E     
#>  8  2013     2     9       NA        830      NA      NA     951      NA EV     
#>  9  2013     2     9       NA        901      NA      NA    1201      NA UA     
#> 10  2013     6    21     1522       1145     217    1723    1358     205 DL     
#> # … with 507 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> #   minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> #   ¹​sched_dep_time, ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

3.1.1 Cvičení

Vyberte lety, které:

  • přiletěly o dvě hodiny později (nebo více), než měly.
  • letěly do Houstonu (dest IAH nebo HOU).
  • provozovaly letecké společnosti United, American nebo Delta Airlines (UA, AA, DL).
  • byly vypraveny během léta (červenec, srpen, září)
  • přiletěly se zpožděním větším než dvě hodiny, ale odletěly bez zpoždění.
  • odletěly se zpožděním větším než hodinu, během letu smazaly ze zpoždění alespoň třicet minut.
  • odletěly mezi půlnocí a šestou hodinou ranní (včetně).

4 Seřazení řádků pomocí arrange()

Funkce arrange() funguje podobně jako filer, ale místo výběru řádků jen mění jejich pořadí. Jako vstupní argumenty má opět použitý dataframe a soubor se jmény sloupců, podle kterých mají být řádky seřazeny, ale i komplikovanější výrazy jsou možné. Pokud použijeme více než jeden sloupec pro seřazení, nejprve se řádky seřadí podle hodnot prvního sloupce a až poté podle hodnot druhého sloupce, existují ji v prvním sloupci nějaké shodné hodnoty. Takto bychom seřadili lety chronologicky podle roku, měsíce a dne odletu.

arrange(flights, year, month, day)
#> # A tibble: 10,000 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     1     1     1842       1422     260    1958    1535     263 EV     
#>  2  2013     1     1     1059       1053       6    1342    1351      -9 UA     
#>  3  2013     1     1      655        700      -5    1002    1020     -18 DL     
#>  4  2013     1     1     1128       1129      -1    1422    1437     -15 UA     
#>  5  2013     1     1     1453       1500      -7    1601    1620     -19 US     
#>  6  2013     1     1     1455       1500      -5    1753    1810     -17 DL     
#>  7  2013     1     1     1720       1725      -5    2121    2105      16 DL     
#>  8  2013     1     1     1740       1630      70    2102    1954      68 DL     
#>  9  2013     1     1     1910       1855      15    2118    2103      15 US     
#> 10  2013     1     1      628        630      -2    1016     947      29 UA     
#> # … with 9,990 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> #   minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> #   ¹​sched_dep_time, ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

V base R by celá operace vyžadovala složitější kód:

# Ve dvou krocích
row_id <- order(flights$year, flights$month, flights$day)

flights[row_id, ]
#> # A tibble: 10,000 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     1     1     1842       1422     260    1958    1535     263 EV     
#>  2  2013     1     1     1059       1053       6    1342    1351      -9 UA     
#>  3  2013     1     1      655        700      -5    1002    1020     -18 DL     
#>  4  2013     1     1     1128       1129      -1    1422    1437     -15 UA     
#>  5  2013     1     1     1453       1500      -7    1601    1620     -19 US     
#>  6  2013     1     1     1455       1500      -5    1753    1810     -17 DL     
#>  7  2013     1     1     1720       1725      -5    2121    2105      16 DL     
#>  8  2013     1     1     1740       1630      70    2102    1954      68 DL     
#>  9  2013     1     1     1910       1855      15    2118    2103      15 US     
#> 10  2013     1     1      628        630      -2    1016     947      29 UA     
#> # … with 9,990 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> #   minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> #   ¹​sched_dep_time, ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

# Ve jednom kroku
flights[order(flights$year, flights$month, flights$day), ] # or in one step
#> # A tibble: 10,000 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     1     1     1842       1422     260    1958    1535     263 EV     
#>  2  2013     1     1     1059       1053       6    1342    1351      -9 UA     
#>  3  2013     1     1      655        700      -5    1002    1020     -18 DL     
#>  4  2013     1     1     1128       1129      -1    1422    1437     -15 UA     
#>  5  2013     1     1     1453       1500      -7    1601    1620     -19 US     
#>  6  2013     1     1     1455       1500      -5    1753    1810     -17 DL     
#>  7  2013     1     1     1720       1725      -5    2121    2105      16 DL     
#>  8  2013     1     1     1740       1630      70    2102    1954      68 DL     
#>  9  2013     1     1     1910       1855      15    2118    2103      15 US     
#> 10  2013     1     1      628        630      -2    1016     947      29 UA     
#> # … with 9,990 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> #   minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> #   ¹​sched_dep_time, ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

Defaultně probíhá zaření vzestupně, ale prostřednictvím pomocné funkce desc() můžeme získat sestupné řazení:

arrange(flights, desc(dep_delay))
#> # A tibble: 10,000 × 19
#>     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     9    20     1139       1845    1014    1457    2210    1007 AA     
#>  2  2013    12     1      657       1930     687    1010    2249     681 DL     
#>  3  2013     3     8     2212       1539     393       1    1735     386 UA     
#>  4  2013     4     9     1519        855     384    1713    1109     364 DL     
#>  5  2013     3    12      133       1910     383     424    2228     356 B6     
#>  6  2013     7    29     1740       1117     383    2009    1335     394 UA     
#>  7  2013     1     2     2131       1512     379    2340    1741     359 UA     
#>  8  2013    10    25     1753       1135     378    2040    1343     417 DL     
#>  9  2013    10    23     1343        730     373    1547     929     378 DL     
#> 10  2013     6    25      104       1900     364     319    2147     332 B6     
#> # … with 9,990 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> #   minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> #   ¹​sched_dep_time, ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

A co chybějící hodnoty? Ty jsou řazeny na konec:

arrange(flights, desc(dep_delay)) %>% 
  tail()
#> # A tibble: 6 × 19
#>    year month   day dep_time sched_dep…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#>   <int> <int> <int>    <int>       <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#> 1  2013     7    22       NA        1330      NA      NA    1625      NA B6     
#> 2  2013     2     8       NA        1800      NA      NA    1914      NA B6     
#> 3  2013     4    19       NA        1345      NA      NA    1453      NA 9E     
#> 4  2013     7    18       NA        2146      NA      NA      30      NA B6     
#> 5  2013    12    15       NA         720      NA      NA    1028      NA UA     
#> 6  2013     3     8       NA        1449      NA      NA    1625      NA EV     
#> # … with 9 more variables: flight <int>, tailnum <chr>, origin <chr>,
#> #   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
#> #   time_hour <dttm>, and abbreviated variable names ¹​sched_dep_time,
#> #   ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

4.1 Cvičení

  • Zkuste přijít na to, jak seřadi chybějící hodnoty na začátek.
  • Seřaďte řádky tak, ať jsou první lety s největším zpožděním při příletu
  • Najděte lety, které odletěly nejdříve z hlediska denního času
  • Najděte lety, které letěly nejrychleji.
  • Najděte lety, které uletěly nejdelší vzdálenost.
  • Najděte lety, které uletěly nejkratší vzdálenost.

5 Výběr sloupců pomocí select()

Protože dataset flights obsahuje pouze 19 proměnných, funkce select() zde není až tak užitečná, nicméně k procvičení jejího použití to vůbec nevadí. Výběr sloupců můžeme provést vypsáním jejich jmen bez uvozovek takto:

select(flights, year, month, day)
#> # A tibble: 10,000 × 3
#>     year month   day
#>    <int> <int> <int>
#>  1  2013     4    26
#>  2  2013     2    26
#>  3  2013     2    15
#>  4  2013     3    27
#>  5  2013     6     5
#>  6  2013     2    16
#>  7  2013     5     1
#>  8  2013    10    20
#>  9  2013    11    11
#> 10  2013     8    31
#> # … with 9,990 more rows

Opět pro přehled můžeme uvést, jak bychom stejné sloupce mohli vybrat v base R:

# Několik možných způsobů
flights[, c("year", "month", "day")]
#> # A tibble: 10,000 × 3
#>     year month   day
#>    <int> <int> <int>
#>  1  2013     4    26
#>  2  2013     2    26
#>  3  2013     2    15
#>  4  2013     3    27
#>  5  2013     6     5
#>  6  2013     2    16
#>  7  2013     5     1
#>  8  2013    10    20
#>  9  2013    11    11
#> 10  2013     8    31
#> # … with 9,990 more rows

flights[c("year", "month", "day")]
#> # A tibble: 10,000 × 3
#>     year month   day
#>    <int> <int> <int>
#>  1  2013     4    26
#>  2  2013     2    26
#>  3  2013     2    15
#>  4  2013     3    27
#>  5  2013     6     5
#>  6  2013     2    16
#>  7  2013     5     1
#>  8  2013    10    20
#>  9  2013    11    11
#> 10  2013     8    31
#> # … with 9,990 more rows

subset(flights, select = c(year, month, day))
#> # A tibble: 10,000 × 3
#>     year month   day
#>    <int> <int> <int>
#>  1  2013     4    26
#>  2  2013     2    26
#>  3  2013     2    15
#>  4  2013     3    27
#>  5  2013     6     5
#>  6  2013     2    16
#>  7  2013     5     1
#>  8  2013    10    20
#>  9  2013    11    11
#> 10  2013     8    31
#> # … with 9,990 more rows

Pokud chceme vybrat všechny sloupce v nějaké “rozpětí”, můžeme to udělat takto pomocí dvojtečky:

select(flights, year:day)
#> # A tibble: 10,000 × 3
#>     year month   day
#>    <int> <int> <int>
#>  1  2013     4    26
#>  2  2013     2    26
#>  3  2013     2    15
#>  4  2013     3    27
#>  5  2013     6     5
#>  6  2013     2    16
#>  7  2013     5     1
#>  8  2013    10    20
#>  9  2013    11    11
#> 10  2013     8    31
#> # … with 9,990 more rows

Kdybychom naopak tyto sloupce chtěli vyřadit, můžeme to udělat takto:

select(flights, -(year:day))
#> # A tibble: 10,000 × 16
#>    dep_t…¹ sched…² dep_d…³ arr_t…⁴ sched…⁵ arr_d…⁶ carrier flight tailnum origin
#>      <int>   <int>   <dbl>   <int>   <int>   <dbl> <chr>    <int> <chr>   <chr> 
#>  1     730     655      35     901     820      41 WN         404 N7735A  LGA   
#>  2    1714    1720      -6    2031    2040      -9 AA        1999 N625AA  EWR   
#>  3    1442    1445      -3    1634    1647     -13 US        1445 N557UW  LGA   
#>  4    1444    1445      -1    1556    1604      -8 9E        3452 N921XJ  JFK   
#>  5    1428    1430      -2    1537    1555     -18 EV        5699 N830AS  LGA   
#>  6     613     600      13     731     735      -4 MQ        3768 N546MQ  EWR   
#>  7     848     850      -2     947    1014     -27 9E        3465 N936XJ  JFK   
#>  8    1918    1855      23    2132    2130       2 DL          87 N1605   JFK   
#>  9     825     835     -10     942    1000     -18 MQ        3355 N0EGMQ  LGA   
#> 10     656     700      -4     904     929     -25 DL        1547 N310NW  LGA   
#> # … with 9,990 more rows, 6 more variables: dest <chr>, air_time <dbl>,
#> #   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>, and abbreviated
#> #   variable names ¹​dep_time, ²​sched_dep_time, ³​dep_delay, ⁴​arr_time,
#> #   ⁵​sched_arr_time, ⁶​arr_delay

select(flights, -c(dep_time, arr_time))
#> # A tibble: 10,000 × 17
#>     year month   day sched_dep_…¹ dep_d…² sched…³ arr_d…⁴ carrier flight tailnum
#>    <int> <int> <int>        <int>   <dbl>   <int>   <dbl> <chr>    <int> <chr>  
#>  1  2013     4    26          655      35     820      41 WN         404 N7735A 
#>  2  2013     2    26         1720      -6    2040      -9 AA        1999 N625AA 
#>  3  2013     2    15         1445      -3    1647     -13 US        1445 N557UW 
#>  4  2013     3    27         1445      -1    1604      -8 9E        3452 N921XJ 
#>  5  2013     6     5         1430      -2    1555     -18 EV        5699 N830AS 
#>  6  2013     2    16          600      13     735      -4 MQ        3768 N546MQ 
#>  7  2013     5     1          850      -2    1014     -27 9E        3465 N936XJ 
#>  8  2013    10    20         1855      23    2130       2 DL          87 N1605  
#>  9  2013    11    11          835     -10    1000     -18 MQ        3355 N0EGMQ 
#> 10  2013     8    31          700      -4     929     -25 DL        1547 N310NW 
#> # … with 9,990 more rows, 7 more variables: origin <chr>, dest <chr>,
#> #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>,
#> #   and abbreviated variable names ¹​sched_dep_time, ²​dep_delay,
#> #   ³​sched_arr_time, ⁴​arr_delay

Dalším způsobem je výběr sloupců pomocí číselných indexů:

select(flights, 4, 7) # Vybrat 4. a 7. sloupec
#> # A tibble: 10,000 × 2
#>    dep_time arr_time
#>       <int>    <int>
#>  1      730      901
#>  2     1714     2031
#>  3     1442     1634
#>  4     1444     1556
#>  5     1428     1537
#>  6      613      731
#>  7      848      947
#>  8     1918     2132
#>  9      825      942
#> 10      656      904
#> # … with 9,990 more rows

select(flights, -c(1:3)) # Vybrat všechny sloupce kromě 1. až 3.
#> # A tibble: 10,000 × 16
#>    dep_t…¹ sched…² dep_d…³ arr_t…⁴ sched…⁵ arr_d…⁶ carrier flight tailnum origin
#>      <int>   <int>   <dbl>   <int>   <int>   <dbl> <chr>    <int> <chr>   <chr> 
#>  1     730     655      35     901     820      41 WN         404 N7735A  LGA   
#>  2    1714    1720      -6    2031    2040      -9 AA        1999 N625AA  EWR   
#>  3    1442    1445      -3    1634    1647     -13 US        1445 N557UW  LGA   
#>  4    1444    1445      -1    1556    1604      -8 9E        3452 N921XJ  JFK   
#>  5    1428    1430      -2    1537    1555     -18 EV        5699 N830AS  LGA   
#>  6     613     600      13     731     735      -4 MQ        3768 N546MQ  EWR   
#>  7     848     850      -2     947    1014     -27 9E        3465 N936XJ  JFK   
#>  8    1918    1855      23    2132    2130       2 DL          87 N1605   JFK   
#>  9     825     835     -10     942    1000     -18 MQ        3355 N0EGMQ  LGA   
#> 10     656     700      -4     904     929     -25 DL        1547 N310NW  LGA   
#> # … with 9,990 more rows, 6 more variables: dest <chr>, air_time <dbl>,
#> #   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>, and abbreviated
#> #   variable names ¹​dep_time, ²​sched_dep_time, ³​dep_delay, ⁴​arr_time,
#> #   ⁵​sched_arr_time, ⁶​arr_delay

select(flights, c(1:4), -2) # Vybrat 1. až 4. sloupec, ale odstranit 2.
#> # A tibble: 10,000 × 3
#>     year   day dep_time
#>    <int> <int>    <int>
#>  1  2013    26      730
#>  2  2013    26     1714
#>  3  2013    15     1442
#>  4  2013    27     1444
#>  5  2013     5     1428
#>  6  2013    16      613
#>  7  2013     1      848
#>  8  2013    20     1918
#>  9  2013    11      825
#> 10  2013    31      656
#> # … with 9,990 more rows

Dalším způsobem je výběr sloupců pomocí vektoru typu character s názvy sloupců. Tento vektor vložíme do pomocné funkce all_of()

x <- c("dep_time", "arr_time", "air_time")

select(flights, all_of(x))
#> # A tibble: 10,000 × 3
#>    dep_time arr_time air_time
#>       <int>    <int>    <dbl>
#>  1      730      901      116
#>  2     1714     2031      178
#>  3     1442     1634       92
#>  4     1444     1556       44
#>  5     1428     1537       44
#>  6      613      731      113
#>  7      848      947       34
#>  8     1918     2132      112
#>  9      825      942      113
#> 10      656      904      107
#> # … with 9,990 more rows

select(flights, -all_of(x)) # Pokud bychom tyto sloupce chtěli vyřadit
#> # A tibble: 10,000 × 16
#>     year month   day sched_dep_…¹ dep_d…² sched…³ arr_d…⁴ carrier flight tailnum
#>    <int> <int> <int>        <int>   <dbl>   <int>   <dbl> <chr>    <int> <chr>  
#>  1  2013     4    26          655      35     820      41 WN         404 N7735A 
#>  2  2013     2    26         1720      -6    2040      -9 AA        1999 N625AA 
#>  3  2013     2    15         1445      -3    1647     -13 US        1445 N557UW 
#>  4  2013     3    27         1445      -1    1604      -8 9E        3452 N921XJ 
#>  5  2013     6     5         1430      -2    1555     -18 EV        5699 N830AS 
#>  6  2013     2    16          600      13     735      -4 MQ        3768 N546MQ 
#>  7  2013     5     1          850      -2    1014     -27 9E        3465 N936XJ 
#>  8  2013    10    20         1855      23    2130       2 DL          87 N1605  
#>  9  2013    11    11          835     -10    1000     -18 MQ        3355 N0EGMQ 
#> 10  2013     8    31          700      -4     929     -25 DL        1547 N310NW 
#> # … with 9,990 more rows, 6 more variables: origin <chr>, dest <chr>,
#> #   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>, and abbreviated
#> #   variable names ¹​sched_dep_time, ²​dep_delay, ³​sched_arr_time, ⁴​arr_delay

Sloupce můžeme vybrat také podle jejich typu. A to takto, kdy určitou testovací funkci (jako is_character nebo is_double) vložíme do pomocné funkce where()

# Všechny sloupce typu character
select(flights, where(is_character))
#> # A tibble: 10,000 × 4
#>    carrier tailnum origin dest 
#>    <chr>   <chr>   <chr>  <chr>
#>  1 WN      N7735A  LGA    MKE  
#>  2 AA      N625AA  EWR    MIA  
#>  3 US      N557UW  LGA    CLT  
#>  4 9E      N921XJ  JFK    BOS  
#>  5 EV      N830AS  LGA    IAD  
#>  6 MQ      N546MQ  EWR    ORD  
#>  7 9E      N936XJ  JFK    BOS  
#>  8 DL      N1605   JFK    ATL  
#>  9 MQ      N0EGMQ  LGA    BNA  
#> 10 DL      N310NW  LGA    ATL  
#> # … with 9,990 more rows

# Všechny sloupce typu integer
select(flights, where(is_integer))
#> # A tibble: 10,000 × 8
#>     year month   day dep_time sched_dep_time arr_time sched_arr_time flight
#>    <int> <int> <int>    <int>          <int>    <int>          <int>  <int>
#>  1  2013     4    26      730            655      901            820    404
#>  2  2013     2    26     1714           1720     2031           2040   1999
#>  3  2013     2    15     1442           1445     1634           1647   1445
#>  4  2013     3    27     1444           1445     1556           1604   3452
#>  5  2013     6     5     1428           1430     1537           1555   5699
#>  6  2013     2    16      613            600      731            735   3768
#>  7  2013     5     1      848            850      947           1014   3465
#>  8  2013    10    20     1918           1855     2132           2130     87
#>  9  2013    11    11      825            835      942           1000   3355
#> 10  2013     8    31      656            700      904            929   1547
#> # … with 9,990 more rows

Pro výběr sloupců existují další pomocné funkce, jako například:

  • starts_with(), která vybírá sloupce, jejichž název začíná určitými znaky.
  • ends_with(), která vybírá sloupce, jejichž název končí určitými znaky.
  • contains(), která vybírá sloupce, jejichž název obsahuje určité znaky.

Tady je ukázka jejich použití:

select(flights, starts_with("dep"))
#> # A tibble: 10,000 × 2
#>    dep_time dep_delay
#>       <int>     <dbl>
#>  1      730        35
#>  2     1714        -6
#>  3     1442        -3
#>  4     1444        -1
#>  5     1428        -2
#>  6      613        13
#>  7      848        -2
#>  8     1918        23
#>  9      825       -10
#> 10      656        -4
#> # … with 9,990 more rows
select(flights, ends_with("time"))
#> # A tibble: 10,000 × 5
#>    dep_time sched_dep_time arr_time sched_arr_time air_time
#>       <int>          <int>    <int>          <int>    <dbl>
#>  1      730            655      901            820      116
#>  2     1714           1720     2031           2040      178
#>  3     1442           1445     1634           1647       92
#>  4     1444           1445     1556           1604       44
#>  5     1428           1430     1537           1555       44
#>  6      613            600      731            735      113
#>  7      848            850      947           1014       34
#>  8     1918           1855     2132           2130      112
#>  9      825            835      942           1000      113
#> 10      656            700      904            929      107
#> # … with 9,990 more rows
select(flights, contains("arr"))
#> # A tibble: 10,000 × 4
#>    arr_time sched_arr_time arr_delay carrier
#>       <int>          <int>     <dbl> <chr>  
#>  1      901            820        41 WN     
#>  2     2031           2040        -9 AA     
#>  3     1634           1647       -13 US     
#>  4     1556           1604        -8 9E     
#>  5     1537           1555       -18 EV     
#>  6      731            735        -4 MQ     
#>  7      947           1014       -27 9E     
#>  8     2132           2130         2 DL     
#>  9      942           1000       -18 MQ     
#> 10      904            929       -25 DL     
#> # … with 9,990 more rows

Existuje také funkce num_range(). Například num_range("x", 1:3) vybere sloupce, které mají názvy x1, x2 a x3. Zde je příklad jejího použití na cvičném dataframe:

my_tibble <- tribble(
  ~x1, ~x2, ~x3, ~x4, ~x5, ~x6,
    1,   2,   3,   4,   5,   6,
    7,   8,   9,  10,  11,  12
)
my_tibble
#> # A tibble: 2 × 6
#>      x1    x2    x3    x4    x5    x6
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1     1     2     3     4     5     6
#> 2     7     8     9    10    11    12

select(my_tibble, num_range("x", 1:3))
#> # A tibble: 2 × 3
#>      x1    x2    x3
#>   <dbl> <dbl> <dbl>
#> 1     1     2     3
#> 2     7     8     9

select(my_tibble, num_range("x", 4:6))
#> # A tibble: 2 × 3
#>      x4    x5    x6
#>   <dbl> <dbl> <dbl>
#> 1     4     5     6
#> 2    10    11    12

Funkci select() můžeme také použít k přejmenování sloupců, a to tímto způsobem :

select(flights, departure_time = dep_time) # novy_nazev = puvodni_nazev
#> # A tibble: 10,000 × 1
#>    departure_time
#>             <int>
#>  1            730
#>  2           1714
#>  3           1442
#>  4           1444
#>  5           1428
#>  6            613
#>  7            848
#>  8           1918
#>  9            825
#> 10            656
#> # … with 9,990 more rows

Musíme ale mít na paměti, že takto vyřadíme všechny sloupce, které explicitně nevybereme. Proto existuje funce rename(), která pouze přejmenovává určené sloupce, ale ostatní ponechává tak, jak jsou.

rename(flights, departure_time = dep_time)
#> # A tibble: 10,000 × 19
#>     year month   day departure…¹ sched…² dep_d…³ arr_t…⁴ sched…⁵ arr_d…⁶ carrier
#>    <int> <int> <int>       <int>   <int>   <dbl>   <int>   <int>   <dbl> <chr>  
#>  1  2013     4    26         730     655      35     901     820      41 WN     
#>  2  2013     2    26        1714    1720      -6    2031    2040      -9 AA     
#>  3  2013     2    15        1442    1445      -3    1634    1647     -13 US     
#>  4  2013     3    27        1444    1445      -1    1556    1604      -8 9E     
#>  5  2013     6     5        1428    1430      -2    1537    1555     -18 EV     
#>  6  2013     2    16         613     600      13     731     735      -4 MQ     
#>  7  2013     5     1         848     850      -2     947    1014     -27 9E     
#>  8  2013    10    20        1918    1855      23    2132    2130       2 DL     
#>  9  2013    11    11         825     835     -10     942    1000     -18 MQ     
#> 10  2013     8    31         656     700      -4     904     929     -25 DL     
#> # … with 9,990 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> #   minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> #   ¹​departure_time, ²​sched_dep_time, ³​dep_delay, ⁴​arr_time, ⁵​sched_arr_time,
#> #   ⁶​arr_delay

Další možností je použití funkce select() v kombinaci s pomocnou funkcí everything(), která vybere všechny zbývající sloupce, což se hodí zejména tehdy, když nějaké sloupce chceme přemístit na začátek datasetu:

select(flights, time_hour, air_time, everything())
#> # A tibble: 10,000 × 19
#>    time_hour           air_t…¹  year month   day dep_t…² sched…³ dep_d…⁴ arr_t…⁵
#>    <dttm>                <dbl> <int> <int> <int>   <int>   <int>   <dbl>   <int>
#>  1 2013-04-26 06:00:00     116  2013     4    26     730     655      35     901
#>  2 2013-02-26 17:00:00     178  2013     2    26    1714    1720      -6    2031
#>  3 2013-02-15 14:00:00      92  2013     2    15    1442    1445      -3    1634
#>  4 2013-03-27 14:00:00      44  2013     3    27    1444    1445      -1    1556
#>  5 2013-06-05 14:00:00      44  2013     6     5    1428    1430      -2    1537
#>  6 2013-02-16 06:00:00     113  2013     2    16     613     600      13     731
#>  7 2013-05-01 08:00:00      34  2013     5     1     848     850      -2     947
#>  8 2013-10-20 18:00:00     112  2013    10    20    1918    1855      23    2132
#>  9 2013-11-11 08:00:00     113  2013    11    11     825     835     -10     942
#> 10 2013-08-31 07:00:00     107  2013     8    31     656     700      -4     904
#> # … with 9,990 more rows, 10 more variables: sched_arr_time <int>,
#> #   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
#> #   dest <chr>, distance <dbl>, hour <dbl>, minute <dbl>, and abbreviated
#> #   variable names ¹​air_time, ²​dep_time, ³​sched_dep_time, ⁴​dep_delay, ⁵​arr_time

Další pomocnou funkcí, která se může hodit, když chceme na začátek datasetu přesunout poslední sloupec, je funkce last_col:

select(flights, last_col(), everything())
#> # A tibble: 10,000 × 19
#>    time_hour            year month   day dep_t…¹ sched…² dep_d…³ arr_t…⁴ sched…⁵
#>    <dttm>              <int> <int> <int>   <int>   <int>   <dbl>   <int>   <int>
#>  1 2013-04-26 06:00:00  2013     4    26     730     655      35     901     820
#>  2 2013-02-26 17:00:00  2013     2    26    1714    1720      -6    2031    2040
#>  3 2013-02-15 14:00:00  2013     2    15    1442    1445      -3    1634    1647
#>  4 2013-03-27 14:00:00  2013     3    27    1444    1445      -1    1556    1604
#>  5 2013-06-05 14:00:00  2013     6     5    1428    1430      -2    1537    1555
#>  6 2013-02-16 06:00:00  2013     2    16     613     600      13     731     735
#>  7 2013-05-01 08:00:00  2013     5     1     848     850      -2     947    1014
#>  8 2013-10-20 18:00:00  2013    10    20    1918    1855      23    2132    2130
#>  9 2013-11-11 08:00:00  2013    11    11     825     835     -10     942    1000
#> 10 2013-08-31 07:00:00  2013     8    31     656     700      -4     904     929
#> # … with 9,990 more rows, 10 more variables: arr_delay <dbl>, carrier <chr>,
#> #   flight <int>, tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>,
#> #   distance <dbl>, hour <dbl>, minute <dbl>, and abbreviated variable names
#> #   ¹​dep_time, ²​sched_dep_time, ³​dep_delay, ⁴​arr_time, ⁵​sched_arr_time

5.0.1 Cvičení

Zkuste vyřešit následující úlohy:

  • Vymyslete co nejvíce možných způsobů, jak z datasetu flights vybrat sloupce dep_time, dep_delay, arr_time a arr_delay
  • Co se stane, když ve funkci select() uvedeme název téhož sloupce vícekrát?
  • K čemu slouží funkce all_of() a any_of()? Zkuste spustit tento kód a pak místo funkce all_of() použít funkci any_of().
x <- c("year", "month", "day", "dep_delay", "arr_delay", "nonexistent")
select(flights, all_of(x))
  • Rozlišují defaultně funkce starts_with(), ends_with() a contains() malá a velká písmena? Vyzkoušejte to na kódu níže a pak zkuste změnit toto defaultní chování:
select(flights, contains("TIME"))

6 Tvorba nových proměnných (sloupců) pomocí mutate()

Pro větší přehlednost budeme pracovat s menším množstvím proměnných:

flights_sml <- select(flights, 
                      year:day, 
                      ends_with("delay"), 
                      distance, 
                      air_time
)

Použití funkce mutate() je docela jednoduché. Prvním argumentem je použitý dataframe. Další argumenty pak stanovují, jak se má jmenovat nová proměnná a jak se má vytvořit. Dejme tomu, že chceme vypočíst rozdíl mezi dep_delay a arr_delay, abychom zjistili, zdali letadlo během letu snížilo, nebo zvýšilo své zpoždění, které mělo při odletu, a tak vytvořit novou proměnnou gain = dep_delay - arr_delay. Dále chceme vypočíst průměrnou rychlost letu v kilometrech za hodinu na základě vzdálenosti (distance) a času samotného letu (air_time). Protože distance je v mílích a air_time s minutách, násobíme distance 1,609 (pro převod na kilometry) a air_time dělíme 60 (pro převod na minuty)

mutate(flights_sml,
       gain = dep_delay - arr_delay, # úbytek zpoždění, resp. získání náskoku během letu
       speed = (distance*1.609) / (air_time / 60) # průměrná rychlost v km/h
)
#> # A tibble: 10,000 × 9
#>     year month   day dep_delay arr_delay distance air_time  gain speed
#>    <int> <int> <int>     <dbl>     <dbl>    <dbl>    <dbl> <dbl> <dbl>
#>  1  2013     4    26        35        41      738      116    -6  614.
#>  2  2013     2    26        -6        -9     1085      178     3  588.
#>  3  2013     2    15        -3       -13      544       92    10  571.
#>  4  2013     3    27        -1        -8      187       44     7  410.
#>  5  2013     6     5        -2       -18      229       44    16  502.
#>  6  2013     2    16        13        -4      719      113    17  614.
#>  7  2013     5     1        -2       -27      187       34    25  531.
#>  8  2013    10    20        23         2      760      112    21  655.
#>  9  2013    11    11       -10       -18      764      113     8  653.
#> 10  2013     8    31        -4       -25      762      107    21  688.
#> # … with 9,990 more rows

FUnkce mutate() je uživatelsky příjemná i proto, že se můžeme odkazovat na právě vytvářené sloupce při tvorbě dalších sloupců:

mutate(flights_sml,
       gain = dep_delay - arr_delay,
       distance_km = distance*1.609,
       air_time_hours = air_time / 60,
       speed_km_per_hour = distance_km / air_time_hours
)
#> # A tibble: 10,000 × 11
#>     year month   day dep_delay arr_delay distance air_time  gain dista…¹ air_t…²
#>    <int> <int> <int>     <dbl>     <dbl>    <dbl>    <dbl> <dbl>   <dbl>   <dbl>
#>  1  2013     4    26        35        41      738      116    -6   1187.   1.93 
#>  2  2013     2    26        -6        -9     1085      178     3   1746.   2.97 
#>  3  2013     2    15        -3       -13      544       92    10    875.   1.53 
#>  4  2013     3    27        -1        -8      187       44     7    301.   0.733
#>  5  2013     6     5        -2       -18      229       44    16    368.   0.733
#>  6  2013     2    16        13        -4      719      113    17   1157.   1.88 
#>  7  2013     5     1        -2       -27      187       34    25    301.   0.567
#>  8  2013    10    20        23         2      760      112    21   1223.   1.87 
#>  9  2013    11    11       -10       -18      764      113     8   1229.   1.88 
#> 10  2013     8    31        -4       -25      762      107    21   1226.   1.78 
#> # … with 9,990 more rows, 1 more variable: speed_km_per_hour <dbl>, and
#> #   abbreviated variable names ¹​distance_km, ²​air_time_hours

Alternativou k funkci mutate() je funkce transmute(). Ta funguje velmi podobně, ale s jedním podstatným rozdílem: Ponechává pouze nově vytvořené sloupce:

transmute(flights_sml,
          gain = dep_delay - arr_delay,
          distance_km = distance*1.609,
          air_time_hours = air_time / 60,
          speed_km_per_hour = distance_km / air_time_hours
)
#> # A tibble: 10,000 × 4
#>     gain distance_km air_time_hours speed_km_per_hour
#>    <dbl>       <dbl>          <dbl>             <dbl>
#>  1    -6       1187.          1.93               614.
#>  2     3       1746.          2.97               588.
#>  3    10        875.          1.53               571.
#>  4     7        301.          0.733              410.
#>  5    16        368.          0.733              502.
#>  6    17       1157.          1.88               614.
#>  7    25        301.          0.567              531.
#>  8    21       1223.          1.87               655.
#>  9     8       1229.          1.88               653.
#> 10    21       1226.          1.78               688.
#> # … with 9,990 more rows

6.0.1 Cvičení

Časy v dep_time jsou srozumitelné, např. číslo 933 znamená 9 hodin a 33 minut, ale nemůžeme s nimi v současné podobě pracovat jako se spojitou proměnnou. Zkuste proto na základě dep_time vytvořit dvě nové proměnné dep_time_hour a dep_time_minute čili “extrahovat” z dep_time hodinu a minutu tak, ať jsou v samostatných sloupcích. Nápověda: bude se vám hodit celočíselné dělení (operátor%/%) a zbytek po celočíselném dělení (%%). Kdybyste chtěli úplně korektní řešení, zkuste si poradit i s tím, že 2400 znamená začátek daného dne, nikoli konec.

Vyzkoušejte si, jak fungují funkce pro výpočet pořadí a jak řeší shodné hodnoty:

x <- c(1, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 7, 8, 9, 10, 10)
# Pro shodné hodnoty se vypočte průměrné pořadí
rank(x)
#>  [1]  2.0  2.0  2.0  4.0  5.5  5.5  7.0  8.5  8.5 10.0 12.0 12.0 12.0 14.0 15.0
#> [16] 16.5 16.5

rank(x, ties.method = "average") 
#>  [1]  2.0  2.0  2.0  4.0  5.5  5.5  7.0  8.5  8.5 10.0 12.0 12.0 12.0 14.0 15.0
#> [16] 16.5 16.5

# Pořadí pro shodné hodnoty podle původního pořadí vzestupně
rank(x, ties.method = "first")
#>  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17

# Pořadí pro shodné hodnoty podle původního pořadí sestupně
rank(x, ties.method = "last")
#>  [1]  3  2  1  4  6  5  7  9  8 10 13 12 11 14 15 17 16

# Pořadí pro shodné hodnoty náhodně
rank(x, ties.method = "random") 
#>  [1]  2  1  3  4  6  5  7  9  8 10 12 11 13 14 15 16 17

# Pořadí pro shodné hodnoty podle pořadí poslední ze shodných hodnot 
rank(x, ties.method = "max") 
#>  [1]  3  3  3  4  6  6  7  9  9 10 13 13 13 14 15 17 17

# Pořadí pro shodné hodnoty podle pořadí první ze shodných hodnot 
rank(x, ties.method = "min")
#>  [1]  1  1  1  4  5  5  7  8  8 10 11 11 11 14 15 16 16

min_rank(x) # Totéž jako rank(x, ties.method = "min")
#>  [1]  1  1  1  4  5  5  7  8  8 10 11 11 11 14 15 16 16

# Kdybychom chtěli rankovat opačně, stačí před vektor dát mínus
min_rank(-x)
#>  [1] 15 15 15 14 12 12 11  9  9  8  5  5  5  4  3  1  1

# Podobné jako min_rank(x), ale bez "mezer" mezi ranky
dense_rank(x) 
#>  [1]  1  1  1  2  3  3  4  5  5  6  7  7  7  8  9 10 10

 # Přeškálování min_rank(x) na rozmezí od 0 do 1
percent_rank(x)
#>  [1] 0.0000 0.0000 0.0000 0.1875 0.2500 0.2500 0.3750 0.4375 0.4375 0.5625
#> [11] 0.6250 0.6250 0.6250 0.8125 0.8750 0.9375 0.9375

# Podíl hodnot menších než daná hodnota nebo rovných (empirická kumulativní distribuční funkce)
cume_dist(x) 
#>  [1] 0.1764706 0.1764706 0.1764706 0.2352941 0.3529412 0.3529412 0.4117647
#>  [8] 0.5294118 0.5294118 0.5882353 0.7647059 0.7647059 0.7647059 0.8235294
#> [15] 0.8823529 1.0000000 1.0000000

# Pouhé pořadí prvků bez ohledu na hodnotu
row_number(x)
#>  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17

# Rozdělí prvky do n-skupin, které jsou zhruba stejně velké
ntile(x, n = 4) 
#>  [1] 1 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4

Vytvořte pomocí mutate() novou proměnnou air_delay udávající nárůst (resp. pokles) zpoždění během letu čili rozdíl mezi arr_delay a dep_delay.

Pak vytvořte proměnnou air_delay_per_hour udávající nárůst zpoždění během letu za každou hodinu letu.

Nakonec vytvořte pomocí funkce min_rank() proměnné air_delay_per_hour_asc a air_delay_per_hour_desc, udávající pořadí letů podle air_delay_per_hour vzestupně a sestupně, a vyberte 10 letů, u kterých za každou hodinut letu narostlo zpoždění během letu nejvíce, a 10 letů, u kterých zpoždění naopak pokleslo nejvíce (resp. získali největší časový náskok) za každou hodinu letu.

7 Souhrnné statistiky pomocí summarise()

Poslední z hlavních funkcí balíčku dplyr je funkce summarise(). Ta se používá zejm. pro výpočet souhrnných statistik, a to například tímto způsobem:

summarise(flights, M_delay = mean(dep_delay, na.rm = TRUE))
#> # A tibble: 1 × 1
#>   M_delay
#>     <dbl>
#> 1    12.3

# To, jak si nově vypočtenou statistiku pojmenujeme, je na nás.
summarise(flights, prumerne_zpozdeni_odletu = mean(dep_delay, na.rm = TRUE))
#> # A tibble: 1 × 1
#>   prumerne_zpozdeni_odletu
#>                      <dbl>
#> 1                     12.3

Užitečnější je ovšem tato funkce v kombinaci s funkcí group_by(). Tou totiž můžeme dataset rozdělit na skupiny a poté pro tyto skupiny vypočíst různé souhrnné statistiky. Takto bychom vypočetli průměrné zpoždění pro každou kombinaci roku/měsíce/dne v měsíci:

by_day <- group_by(flights, year, month, day)
summarise(by_day, delay = mean(dep_delay, na.rm = TRUE))
#> `summarise()` has grouped output by 'year', 'month'. You can override using the
#> `.groups` argument.
#> # A tibble: 365 × 4
#> # Groups:   year, month [12]
#>     year month   day  delay
#>    <int> <int> <int>  <dbl>
#>  1  2013     1     1 25.1  
#>  2  2013     1     2 18.5  
#>  3  2013     1     3 11.9  
#>  4  2013     1     4  6.05 
#>  5  2013     1     5  0.643
#>  6  2013     1     6  7.36 
#>  7  2013     1     7  1.12 
#>  8  2013     1     8 -3.88 
#>  9  2013     1     9 -2.82 
#> 10  2013     1    10 -0.6  
#> # … with 355 more rows

Protože často potřebujeme dataset rozdělit různě a vytvářet pokaždé nový, jinak rozdělený dataset (jako v tomto případě by_day) může být zbytečné, často využíváme pipe (%>%) ke zřetězení více operací dohromady.

flights %>% # použitý dataset
  group_by(year, month, day) %>% # rozdělit podle
  summarise(delay = mean(dep_delay, na.rm = TRUE)) %>% # Vypočíst statistiky
  arrange(desc(delay)) # seřadit podle
#> `summarise()` has grouped output by 'year', 'month'. You can override using the
#> `.groups` argument.
#> # A tibble: 365 × 4
#> # Groups:   year, month [12]
#>     year month   day delay
#>    <int> <int> <int> <dbl>
#>  1  2013     3     8 113. 
#>  2  2013     5     8  70.0
#>  3  2013     6    13  58.4
#>  4  2013     5    23  57.9
#>  5  2013     6    28  52.8
#>  6  2013     7     1  52.7
#>  7  2013     9    20  52.7
#>  8  2013     8     1  52.3
#>  9  2013     8     9  51.5
#> 10  2013     8     8  51.0
#> # … with 355 more rows

Na argument na.rm`` už jsme natrefili. Co se stane, když jej nespecifikujeme a ponecháme defaultní nastavení (které jena.rm = FALSE`)?

flights %>% 
  group_by(year, month, day) %>% 
  summarise(delay = mean(dep_delay)) %>% 
  arrange(!is.na(delay))
#> `summarise()` has grouped output by 'year', 'month'. You can override using the
#> `.groups` argument.
#> # A tibble: 365 × 4
#> # Groups:   year, month [12]
#>     year month   day delay
#>    <int> <int> <int> <dbl>
#>  1  2013     1    11    NA
#>  2  2013     1    16    NA
#>  3  2013     1    23    NA
#>  4  2013     1    25    NA
#>  5  2013     1    28    NA
#>  6  2013     1    30    NA
#>  7  2013     1    31    NA
#>  8  2013     2     1    NA
#>  9  2013     2     3    NA
#> 10  2013     2     4    NA
#> # … with 355 more rows

Dostaneme hodně chybějících hodnot, protože pokud se průměr počítá z dat, ve kterých je byť jen jedna chybějí hodnota, výsledek bude také NA. Kromě nastavení argumentu na.rm = TRUE bychom to mohli vyřešit také tak, že nejprve odstraníme z dat lety, které byly zrušeny:

not_cancelled <- flights %>% 
  filter(!is.na(dep_delay), !is.na(arr_delay))

not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(mean = mean(dep_delay))
#> `summarise()` has grouped output by 'year', 'month'. You can override using the
#> `.groups` argument.
#> # A tibble: 365 × 4
#> # Groups:   year, month [12]
#>     year month   day   mean
#>    <int> <int> <int>  <dbl>
#>  1  2013     1     1 25.1  
#>  2  2013     1     2 18.5  
#>  3  2013     1     3 11.9  
#>  4  2013     1     4  6.05 
#>  5  2013     1     5  0.643
#>  6  2013     1     6  7.36 
#>  7  2013     1     7  1.12 
#>  8  2013     1     8 -3.88 
#>  9  2013     1     9 -2.82 
#> 10  2013     1    10 -0.6  
#> # … with 355 more rows

Kdykoli ale takto pracujeme s daty, měli bychom mít přehled o tom, kolik pozorování nám v každé skupině zbylo. Pokud jsme chybějící hodnoty předem vyřadili, můžeme k tomu použít funkci n(), která vypočte počet pozorování (řádků) v jednotlivých skupinách.

not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(M = mean(dep_delay),
            SD = sd(dep_delay),
            n = n())
#> `summarise()` has grouped output by 'year', 'month'. You can override using the
#> `.groups` argument.
#> # A tibble: 365 × 6
#> # Groups:   year, month [12]
#>     year month   day      M    SD     n
#>    <int> <int> <int>  <dbl> <dbl> <int>
#>  1  2013     1     1 25.1   61.3     19
#>  2  2013     1     2 18.5   69.5     31
#>  3  2013     1     3 11.9   27.6     32
#>  4  2013     1     4  6.05  17.1     20
#>  5  2013     1     5  0.643  7.14    28
#>  6  2013     1     6  7.36  20.6     28
#>  7  2013     1     7  1.12  11.4     16
#>  8  2013     1     8 -3.88   3.03    24
#>  9  2013     1     9 -2.82   6.04    22
#> 10  2013     1    10 -0.6    9.33    20
#> # … with 355 more rows

Jinak můžeme použít funkci sum() v kombinaci s !is.na(), abychom získali počet validních (nechybějících) hodnot.

flights %>% 
  group_by(year, month, day) %>% 
  summarise(M_delay = mean(dep_delay, na.rm = TRUE),
            SD_delay = sd(dep_delay, na.rm = TRUE),
            n_delay = sum(!is.na(dep_delay))) %>% 
  arrange(desc(M_delay))
#> `summarise()` has grouped output by 'year', 'month'. You can override using the
#> `.groups` argument.
#> # A tibble: 365 × 6
#> # Groups:   year, month [12]
#>     year month   day M_delay SD_delay n_delay
#>    <int> <int> <int>   <dbl>    <dbl>   <int>
#>  1  2013     3     8   113.     110.       21
#>  2  2013     5     8    70.0     88.3      28
#>  3  2013     6    13    58.4     71.9      26
#>  4  2013     5    23    57.9    103.       27
#>  5  2013     6    28    52.8     68.8      25
#>  6  2013     7     1    52.7     53.9      31
#>  7  2013     9    20    52.7    216.       22
#>  8  2013     8     1    52.3     72.5      25
#>  9  2013     8     9    51.5     68.8      31
#> 10  2013     8     8    51.0     67.7      30
#> # … with 355 more rows

7.1 Užitečné statistické funkce

Míry střední hodnoty. Zatím jsme počítali průměr, ale medián může být také užitečný. Také si můžeme ukázat, že subseting vektorů funguje i v rámci funkce summarise(). Například si můžeme spočítat průměrný a mediánový arrival delay (zpoždění při příletu) pouze pro pozitivní hodnoty arrival delay (tj. pro lety, které skutečně měly zpoždý přílet, protože záporný arrival delay vlastně znamená, že letadlo doletělo do cílové destinace dříve, než mělo).

not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(
    # Medián arrival delays
    Mdn_delay = median(arr_delay),
    # Medián pouze pro pozitivní arrival delays
    Mdn_pos_delay = median(arr_delay[arr_delay > 0]),
    # Průměr arrival delays
    M_pos_delay = mean(arr_delay),
    # Průměr pouze pro pozitivní arrival delays
    M_delay = mean(arr_delay[arr_delay > 0]) 
  )
#> `summarise()` has grouped output by 'year', 'month'. You can override using the
#> `.groups` argument.
#> # A tibble: 365 × 7
#> # Groups:   year, month [12]
#>     year month   day Mdn_delay Mdn_pos_delay M_pos_delay M_delay
#>    <int> <int> <int>     <dbl>         <dbl>       <dbl>   <dbl>
#>  1  2013     1     1      15            21         26.6    49.6 
#>  2  2013     1     2       6            25.5       20.5    46.7 
#>  3  2013     1     3       5            13         11.5    27.3 
#>  4  2013     1     4      -8            15        -10.2    14.1 
#>  5  2013     1     5      -6             6         -5.89    8.12
#>  6  2013     1     6       4.5          12.5        6.21   21.2 
#>  7  2013     1     7      -8.5           5         -7.81    8.2 
#>  8  2013     1     8     -10             6.5      -11.2     6.25
#>  9  2013     1     9      -4.5           7         -8.27    8.5 
#> 10  2013     1    10     -16             9        -15.0    16.7 
#> # … with 355 more rows

Míry variability:

  • sd(x): směrodatná ochylka.
  • IQR(x): mezikvartilové rozpětí.
  • `mad(x)``: mediánová absolutní odchylka od mediánu.
not_cancelled %>% 
  group_by(dest) %>% 
  summarise(SD_distance = sd(distance),
            IQR_distance = IQR(distance),
            MAD_distance = mad(distance))
#> # A tibble: 97 × 4
#>    dest  SD_distance IQR_distance MAD_distance
#>    <chr>       <dbl>        <dbl>        <dbl>
#>  1 ABQ          0               0            0
#>  2 ACK          0               0            0
#>  3 ALB          0               0            0
#>  4 ATL          7.24           16            0
#>  5 AUS          8.50           17            0
#>  6 AVL          5.66            0            0
#>  7 BDL          0               0            0
#>  8 BGR          0               0            0
#>  9 BHM          0               0            0
#> 10 BNA          7.68           16            0
#> # … with 87 more rows

Pořadové statistiky:

  • min(x): minimální hodnota.
  • quantile(x, q): jakýkoli kvantil q.
  • max(x): maximální hodnota.
not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(
    Min = min(dep_time),
    q25 = quantile(dep_time, 0.25),
    Mdn = median(dep_time),
    q75 = quantile(dep_time, 0.75),
    Max = max(dep_time)
  )
#> `summarise()` has grouped output by 'year', 'month'. You can override using the
#> `.groups` argument.
#> # A tibble: 365 × 8
#> # Groups:   year, month [12]
#>     year month   day   Min   q25   Mdn   q75   Max
#>    <int> <int> <int> <int> <dbl> <dbl> <dbl> <int>
#>  1  2013     1     1   628 1180. 1720  1876   2026
#>  2  2013     1     2   616  834. 1213  1530.  2131
#>  3  2013     1     3   556  840. 1336. 1657.  2113
#>  4  2013     1     4   650  888  1280. 1512.  2006
#>  5  2013     1     5   534  719. 1376. 1714   2153
#>  6  2013     1     6   558  906. 1278  1569   2008
#>  7  2013     1     7   620 1196. 1608. 1755.  1937
#>  8  2013     1     8   625  908. 1392. 1554.  1955
#>  9  2013     1     9   524  757  1179  1547   1925
#> 10  2013     1    10    16  905  1242. 1556.  1955
#> # … with 355 more rows

Četnosti. Už jsme se setkali s funkcí n(), která nepotřebuje žádné argumenty a informuje o velikosti skupin. Poče validních (nechybějících) hodnot v x pak můžeme získat pomocí sum(!is.na(x)). Další užitečná funkce je funkce n_distinct(x), která zjišťuje počet jedinečnýc hodnot. Takto bychom např. získali počet všech letů, počet nezrušených letů a počet dopravců létajících do dané destinace.

flights %>%
  group_by(dest) %>% 
  summarise(
    # Počet všech letů
    n_all = n(),
    # Počet nezřušených letů
    n_not_cancelled = sum(!is.na(dep_time) & !is.na(arr_time)), 
    # Počet jedinečných dopravců
    n_carriers = n_distinct(carrier)
  ) %>% 
  arrange(desc(n_all))
#> # A tibble: 98 × 4
#>    dest  n_all n_not_cancelled n_carriers
#>    <chr> <int>           <int>      <int>
#>  1 ATL     530             522          7
#>  2 ORD     513             495          5
#>  3 LAX     497             495          5
#>  4 BOS     485             466          7
#>  5 MCO     429             428          4
#>  6 SFO     416             414          5
#>  7 CLT     410             400          6
#>  8 MIA     380             376          3
#>  9 FLL     338             329          4
#> 10 DTW     309             301          5
#> # … with 88 more rows

S četnostmi pracujeme tak často, že pro ně má dplyr zvláštní funkci count(). Kdybychom chtěli vědět počet letů, které měli různí přepravci do Atlanty a Aucklandu, můžeme postupovat takto:

flights %>% 
  filter(dest %in% c("ATL", "ACK")) %>% # Filtr destinací
  count(dest, carrier) # Četnosti pro jednotlivé kombinace destinace/přepravce
#> # A tibble: 8 × 3
#>   dest  carrier     n
#>   <chr> <chr>   <int>
#> 1 ACK   B6          9
#> 2 ATL   9E          4
#> 3 ATL   DL        318
#> 4 ATL   EV         58
#> 5 ATL   FL         75
#> 6 ATL   MQ         69
#> 7 ATL   UA          4
#> 8 ATL   WN          2

7.1.1 Cvičení

Rozšiřte předchozí kód tak, abyste vypočetli i relativní četnosti letů různých dopravců pro obě destinace zvlášť destinaci. Budeme k tomu potřebovat použít group_by() a mutate().