Пакет dplyr и набор данных flights

На прошлом занятии мы поговорили о том, откуда можно взять данные, и как их импортировать. Но почти всегда данные приходят не в том виде, в котором нам хотелось бы. Поэтому перед тем как приступать к визуализации или построению модели, нужно обработать наши данные. В этом нам поможет пакет dplyr, который входит в библиотеку tidyverse.

Мы рассмотрим основные функции этого пакета:

  • filter
  • arrange
  • select
  • mutate
  • summarize
  • group_by

Функции из этого пакеты мы будем использовать на датасете flights, который находится в пакете nycflights13.В этом датасете содержится информация о всех авиарейсах аэропортов Нью-Йорка, совершенных в 2013 году. Описание датасета можно получить выполнив команду ?flights.

Давайте подгрузим наши пакеты .

Посмотрим на наш датасет.

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

Значение некоторых переменных:

  • year, month, day – дата отправления
  • dep_time, arr_time – aактическое время отправления и прибытия (формат HHMM или HMM)
  • sched_dep_time, sched_arr_time – запланированное время отправления и прибытия (формат HHMM или HMM)
  • dep_delay, arr_delay – задержка вылета и прилет (в минутах)
  • carrier – сокращенное название авиакомпании (в датасете airlines можно найти полное название)
  • flight – номер рейса
  • tailnum – номер самолета (в датасете planes можно узнать больше о самолете)
  • origin, dest – сокращенное название аэропорта отбытия и прибытия
  • air_time – общее время в воздухе (в минутах)
  • distance – дистанция между аэропортами в милях

А теперь начнем изучать возможности пакета dplyr!

filter

С помощью функции filter вы можете отбирать наблюдения по каким-то критериям. Первым аргументом функции является название датасета (df). Последующие аргументы это логические выражения, которые обеспечивают отбор (фильтрацию). Давайте попробуем использовать эту функцию на практике.

## # A tibble: 27,004 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1  2013     1     1      517            515         2      830
##  2  2013     1     1      533            529         4      850
##  3  2013     1     1      542            540         2      923
##  4  2013     1     1      544            545        -1     1004
##  5  2013     1     1      554            600        -6      812
##  6  2013     1     1      554            558        -4      740
##  7  2013     1     1      555            600        -5      913
##  8  2013     1     1      557            600        -3      709
##  9  2013     1     1      557            600        -3      838
## 10  2013     1     1      558            600        -2      753
## # … with 26,994 more rows, and 12 more variables: sched_arr_time <int>,
## #   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <dttm>

Данная функция на выходе выдаёт df c авиарейсами, которые были совершены в январе. Наше логическое выражение строится следующим образом: выбираем название колонки и сравниваем его с какими-либо значения. Важно отметить, что названия колонок не находятся в кавычках.

Чтобы эффективно пользоваться данной функцией, нужно вспомнить операторы сравнения:

  • > – больше
  • < – меньше
  • >= – больше или равно
  • <= – меньше или равно
  • == – равно
  • != – не равно

Вы можете смело использовать их для составления логических выражений. Помним, что один знак равно (=) – это оператор присваивания, а два знака равно (==) – оператор сравнения.

Функция не поменяла датасет flights. Если вы хотите запомнить результат, то вам нужно присвоить его какой-нибудь переменной.

Помним, что при сравнении могут возникнуть некоторые проблемы, связанные с точностью.

Чтобы избежать такого рода проблемы лучше использовать функцию near вместо ==.

Если передавать функции filter несколько аргументов, то мы увидим только те наблюдения, которые удовлетворяют всем условиям, то есть будет использоваться логический оператор И.

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

Давайте вспомним основные логические операторы:

  • И – наблюдения, которые удовлетворяют всем условиям (&).
  • ИЛИ – наблюдения, которые удовлетворяют хотя бы одному условию (|).
  • НЕ – наблюдения, которые не удовлетворяют данному условию (!).
  • XOR – наблюдения, которые не удовлетворяют обоим условиям, то есть дополнение к И (xor()).

НЕЛЬЗЯ использовать && и ||, которые мы привыкли использовать ранее.

Посмотрим как ими можно пользоваться.

## # A tibble: 57,039 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1  2013     5     1        9           1655       434      308
##  2  2013     5     1      451            500        -9      641
##  3  2013     5     1      537            540        -3      836
##  4  2013     5     1      544            545        -1      818
##  5  2013     5     1      548            600       -12      831
##  6  2013     5     1      549            600       -11      804
##  7  2013     5     1      553            600        -7      700
##  8  2013     5     1      553            600        -7      655
##  9  2013     5     1      554            600        -6      731
## 10  2013     5     1      554            600        -6      707
## # … with 57,029 more rows, and 12 more variables: sched_arr_time <int>,
## #   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <dttm>

Данный запрос выведет все авиарейсы за май и июнь. Важно понимать, что записывать запрос таким образом: filter(flights, month == 5|6) НЕЛЬЗЯ!.

Когда значений для одного столбца достаточно много, то не очень удобно записывать все это для каждого значения. На помощь приходит выражение %in%. Его можно использовать как в коде, так и в работе с данными. Ниже можно увидеть два одинаковых выражения, но второе намного приятнее.

Старайтесь не создавать сложные запросы.

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

Данный запрос выводит все авиарейсы с зарержкой не более 2 часов (как по прибытию, так и по отправке). Запрос выглядит очень сложно. Старайтесь этого избегать. Например, если вспомнить законы де Моргана из дискретной математики, то можно его упростить.

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

Важно также разобраться с отсутствующими значениями (NA). Чтобы проверить является ли значение равным NA, нужно использовать функцию is.na. C помощью этой функции можно убрать наблюдения, по которым у нас нет данных.

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

arrange

С помощью функции arrange вы можете отсортировать ваш датафрейм. Первым аргументом функции является название датасета (df). Последующие аргументы это названия столбцов, по которым идет сортировка.

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

С помощью такого запроса мы отсортировали сначала года, потом месяцы для каждого года, а потом дни в каждом месяце. Порядок аргументов здесь очень важен! Можно убедиться на примере ниже.

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

Если вы хотите отсортировать по убыванию, то можете использовать функцию desc.

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

Важно знать, что отсутствующие значения (NA) будут находиться в самом конце после сортировки.

select

Часто бывает, что в данных очень много переменных, но вам нужны только некоторые. С помощью функции select вы можете сделать это. Первым аргументом функции является название датасета (df). Последующие аргументы это переменные (название стобцов), которые вам нужны.

С помощью запроса ниже мы выбрали переменные:

  • year
  • month
  • 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

А с помощью такого мы выбрали все переменные, которые находятся между 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

Аналогичный запрос, но с индексами столбцов.

## # 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

Если вы хотите увидеть все столбцы за исключением каких-то, то можно воспользоваться знаком -.

## # A tibble: 336,776 x 16
##    dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay
##       <int>          <int>     <dbl>    <int>          <int>     <dbl>
##  1      517            515         2      830            819        11
##  2      533            529         4      850            830        20
##  3      542            540         2      923            850        33
##  4      544            545        -1     1004           1022       -18
##  5      554            600        -6      812            837       -25
##  6      554            558        -4      740            728        12
##  7      555            600        -5      913            854        19
##  8      557            600        -3      709            723       -14
##  9      557            600        -3      838            846        -8
## 10      558            600        -2      753            745         8
## # … with 336,766 more rows, and 10 more variables: carrier <chr>,
## #   flight <int>, tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>,
## #   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

Такие запросы можно комбинировать. Можно взять первые десять столбцов за исключением 2.

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

Когда переменных очень много, то такой способ становиться неудобным. На помощь приходят вспомогательные функции:

  • starts_with('abc') – отбирает столбцы, которые начинаются c abc.
  • ends_with('xyz') – отбирает столбцы, которые заканчиваются на xyz.
  • contains('ijk') – обирает столбцы, которые содержат последовательность символов ijk.
  • matches('(.)\\1') – обирает столбцы, которые удовлетворяют регулярному выражению.
  • num_range("x", 1:5) – отбирает столбцы с названием x1, x2, x3, x4, x5.
  • one_of(vars) – выбирает столбцы, название которых находится в векторе vars. Если какого-то столбца нет, то выдаст предупреждение, но не ошибку(если бы мы не использовали функцию).

Более подробно об этих и других вспомогательных функциях можно узнать с помощью команды ?select_helpers.

Давайте попробуем их применить. Допустим нам нужные только данные, которые связаны с прилётом.

## # A tibble: 336,776 x 4
##    arr_time sched_arr_time arr_delay carrier
##       <int>          <int>     <dbl> <chr>  
##  1      830            819        11 UA     
##  2      850            830        20 UA     
##  3      923            850        33 AA     
##  4     1004           1022       -18 B6     
##  5      812            837       -25 DL     
##  6      740            728        12 UA     
##  7      913            854        19 B6     
##  8      709            723       -14 EV     
##  9      838            846        -8 B6     
## 10      753            745         8 AA     
## # … with 336,766 more rows

Появился лишний столбец carrier, но нам уже проще работать с таким датасетом (df).

Есть еще одна вспомогательная everything(). Она помогает перенести некоторые переменные в начало датафрейма. Это бывает удобно, если вы хотите сохранить переменные, но изменить их порядок. Давайте перенесем переменные air_time и time_hour вперёд, а остальные переменные пойдут за ними.

## # A tibble: 336,776 x 19
##    air_time time_hour            year month   day dep_time sched_dep_time
##       <dbl> <dttm>              <int> <int> <int>    <int>          <int>
##  1      227 2013-01-01 05:00:00  2013     1     1      517            515
##  2      227 2013-01-01 05:00:00  2013     1     1      533            529
##  3      160 2013-01-01 05:00:00  2013     1     1      542            540
##  4      183 2013-01-01 05:00:00  2013     1     1      544            545
##  5      116 2013-01-01 06:00:00  2013     1     1      554            600
##  6      150 2013-01-01 05:00:00  2013     1     1      554            558
##  7      158 2013-01-01 06:00:00  2013     1     1      555            600
##  8       53 2013-01-01 06:00:00  2013     1     1      557            600
##  9      140 2013-01-01 06:00:00  2013     1     1      557            600
## 10      138 2013-01-01 06:00:00  2013     1     1      558            600
## # … with 336,766 more rows, and 12 more variables: dep_delay <dbl>,
## #   arr_time <int>, sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
## #   flight <int>, tailnum <chr>, origin <chr>, dest <chr>, distance <dbl>,
## #   hour <dbl>, minute <dbl>

С помощью функции select можно переименовать переменные, но при этом останутся только те переменные, которые вы переименовали.

## # A tibble: 336,776 x 1
##      Год
##    <int>
##  1  2013
##  2  2013
##  3  2013
##  4  2013
##  5  2013
##  6  2013
##  7  2013
##  8  2013
##  9  2013
## 10  2013
## # … with 336,766 more rows

Для того, чтобы переименовать какой-то столбец, но оставить все остальные, можно использовать функцию rename.

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

mutate

С помощью функции mutate вы сможете создавать новые переменные, основанные на уже существующих. Первым аргументом функции является название датасета (df). Последующие аргументы выглядят следующим образом:

название новой переменной = операции с существующими переменными

Новые переменные добавляются в конец df. Поэтому давайте уменьшим наш df, чтобы мы могли увидеть новые переменные.

Давайте создадим переменную speed. Она будет показывать среднюю скорость самолёта.

## # A tibble: 336,776 x 6
##     year month   day distance air_time speed_ml
##    <int> <int> <int>    <dbl>    <dbl>    <dbl>
##  1  2013     1     1     1400      227     370.
##  2  2013     1     1     1416      227     374.
##  3  2013     1     1     1089      160     408.
##  4  2013     1     1     1576      183     517.
##  5  2013     1     1      762      116     394.
##  6  2013     1     1      719      150     288.
##  7  2013     1     1     1065      158     404.
##  8  2013     1     1      229       53     259.
##  9  2013     1     1      944      140     405.
## 10  2013     1     1      733      138     319.
## # … with 336,766 more rows

Умножаем на 60, так как время дано в минутах. Данная скорость мили/час. На только что созданные переменные можно сразу же ссылаться. Давайте найдем скорость км/час.

## # A tibble: 336,776 x 7
##     year month   day distance air_time speed_ml speed_km
##    <int> <int> <int>    <dbl>    <dbl>    <dbl>    <dbl>
##  1  2013     1     1     1400      227     370.     596.
##  2  2013     1     1     1416      227     374.     603.
##  3  2013     1     1     1089      160     408.     657.
##  4  2013     1     1     1576      183     517.     832.
##  5  2013     1     1      762      116     394.     635.
##  6  2013     1     1      719      150     288.     463.
##  7  2013     1     1     1065      158     404.     651.
##  8  2013     1     1      229       53     259.     417.
##  9  2013     1     1      944      140     405.     651.
## 10  2013     1     1      733      138     319.     513.
## # … with 336,766 more rows

Если вы хотите выделить только те переменные, которые только создали вы можете использовать функцию transmute.

## # A tibble: 336,776 x 2
##    speed_ml speed_km
##       <dbl>    <dbl>
##  1     370.     596.
##  2     374.     603.
##  3     408.     657.
##  4     517.     832.
##  5     394.     635.
##  6     288.     463.
##  7     404.     651.
##  8     259.     417.
##  9     405.     651.
## 10     319.     513.
## # … with 336,766 more rows

Существует много функций для создания новых переменных. Все они должны быть векторизованы. Ознакомимся с основынми функциями.

Арифметические операторы:

  • + – сложение
  • - – вычитаение
  • * – умножение
  • / – деление
  • ^ – возведение в степень
  • %/% – целочисленное деление
  • %% – взятие остатка
## # A tibble: 336,776 x 6
##     year month   day distance air_time `air_time/60`
##    <int> <int> <int>    <dbl>    <dbl>         <dbl>
##  1  2013     1     1     1400      227         3.78 
##  2  2013     1     1     1416      227         3.78 
##  3  2013     1     1     1089      160         2.67 
##  4  2013     1     1     1576      183         3.05 
##  5  2013     1     1      762      116         1.93 
##  6  2013     1     1      719      150         2.5  
##  7  2013     1     1     1065      158         2.63 
##  8  2013     1     1      229       53         0.883
##  9  2013     1     1      944      140         2.33 
## 10  2013     1     1      733      138         2.3  
## # … with 336,766 more rows

В наборе данных flights из столбца dep_time можно извлечь часы и минуты.

## # A tibble: 336,776 x 3
##    dep_time  hour minute
##       <int> <dbl>  <dbl>
##  1      517     5     17
##  2      533     5     33
##  3      542     5     42
##  4      544     5     44
##  5      554     5     54
##  6      554     5     54
##  7      555     5     55
##  8      557     5     57
##  9      557     5     57
## 10      558     5     58
## # … with 336,766 more rows

Логарифмические операторы:

  • log() – натуральный логарифм
  • log2() – логарифм с основанием 2
  • log10() – логарифм с основанием 10

Полезно использовать, когда данные охватывают огромный диапозон.

## # A tibble: 336,776 x 2
##    distance log_distance
##       <dbl>        <dbl>
##  1     1400         7.24
##  2     1416         7.26
##  3     1089         6.99
##  4     1576         7.36
##  5      762         6.64
##  6      719         6.58
##  7     1065         6.97
##  8      229         5.43
##  9      944         6.85
## 10      733         6.60
## # … with 336,766 more rows

Смещения:

  • lead() – ссылка на следующие значение
  • lag() – ссылка на предыдущее значение
##  [1] NA  1  2  3  4  5  6  7  8  9
##  [1]  2  3  4  5  6  7  8  9 10 NA

Удобно находить доли x - lag(x) или определять изменилось ли значение x != lag(x). Удобно использовать с функцией group_by, о которой поговорим далее.

Кумулятативные и скользящие агрегаты:

  • cumsum()
  • cumprod()
  • cummin()
  • cummax()
  • cummean()
##  [1]  1  2  3  4  5  6  7  8  9 10
##  [1]  1  3  6 10 15 21 28 36 45 55
##  [1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5

Если вы хотите находить скользящие в пределах “окна”, то используйте пакет RcppRoll.

Логические операторы сравнения:

  • > – больше
  • < – меньше
  • >= – больше или равно
  • <= – меньше или равно
  • == – равно
  • != – не равно
## # A tibble: 336,776 x 6
##     year month   day distance air_time `air_time > 120`
##    <int> <int> <int>    <dbl>    <dbl> <lgl>           
##  1  2013     1     1     1400      227 TRUE            
##  2  2013     1     1     1416      227 TRUE            
##  3  2013     1     1     1089      160 TRUE            
##  4  2013     1     1     1576      183 TRUE            
##  5  2013     1     1      762      116 FALSE           
##  6  2013     1     1      719      150 TRUE            
##  7  2013     1     1     1065      158 TRUE            
##  8  2013     1     1      229       53 FALSE           
##  9  2013     1     1      944      140 TRUE            
## 10  2013     1     1      733      138 TRUE            
## # … with 336,766 more rows

group_by and summarize

Функция summarize позволяет свертывать набор данных в одну строчку. Например найти среднее по столбцу dep_delay.

## # A tibble: 1 x 1
##   delay
##   <dbl>
## 1  12.6

Также можно найти:

  • sum – сумму
  • min – минимальное значение
  • max – максимальное значение
  • mean – среднее значение
  • var – дисперсию
  • median – медиану
  • sd – среднеквадратическое отклонение
  • IQR – межквартильный размах
  • mad – медианное абсолютное отклонение
  • quantile(x, 0.25) – определенный квантиль(в данном примере 25%)
  • n() – количество элементов(можно использовать функцию count)
  • sum(!is.na(x)) – количество элементов не равных NA
  • n_distinct – количество уникальных элементов
  • sum(x > 10) – количество элементов больше 10
  • mean(x == 0) – доля элементов равных 0 от общего количества

Эта функция не очень полезна, если используется не в связке с функцией group_by. Данная функция группирует данные по заданным переменным. Допустим мы хотим найти среднее значение задержки вылета для каждого дня.

## # A tibble: 365 x 4
## # Groups:   year, month [12]
##     year month   day delay
##    <int> <int> <int> <dbl>
##  1  2013     1     1 11.5 
##  2  2013     1     2 13.9 
##  3  2013     1     3 11.0 
##  4  2013     1     4  8.95
##  5  2013     1     5  5.73
##  6  2013     1     6  7.15
##  7  2013     1     7  5.42
##  8  2013     1     8  2.55
##  9  2013     1     9  2.28
## 10  2013     1    10  2.84
## # … with 355 more rows

Можно устранить группирование с помощью функции ungroup.

pipe(%>%)

Так называемый “канал” облегчает написание кода. Давайте поймем как он работает на простом примере. Предположим у нас есть массив x и мы хотим найти его среднее. Мы бы сделали это так.

## [1] 5.5

Но эту же операцию можно проделать с помощью pipe (%>%).

## [1] 5.5

Можно задаться вопросом, зачем делать так, а не как раньше? Давайте представим, что нам дан массив. Нам нужно возвести все элементы в квадрат, найти среднее, а потом взять от него корень. Это можно сделать 2 способами.

Вариант №1
Вариант №2

У каждого варианта есть свои минусы. В первом случае кода очень много , и мы создаем очень много переменных. Во втором случае код короткий, но читать его очень неудобно. Все эти операции можно было сделать с помощью pipe(%>%).

## [1] 6.204837

Данный код убирает эти две проблемы. Его можно читать в повелительном наклонении слева направо. Заметим, что он заменяет первый аргумент функций. Это очень удобно использовать в пакете dplyr, так как первым аргументом функций является df.

Предположим, что мы проводим какие-то манимуляции с нашими данными, то есть применяем функции, которые мы изучили. К примеру выберем столбцы year, month, day и dep_delay. Отберем наблюдения где dep_delay > 0. Сгруппируем их по дням и найдем для каждого среднее значение dep_delay.

## # A tibble: 365 x 4
## # Groups:   year, month [12]
##     year month   day mean_dep_delay
##    <int> <int> <int>          <dbl>
##  1  2013     1     1           32.7
##  2  2013     1     2           32.6
##  3  2013     1     3           28.5
##  4  2013     1     4           26.2
##  5  2013     1     5           21.8
##  6  2013     1     6           22.0
##  7  2013     1     7           26.2
##  8  2013     1     8           21.2
##  9  2013     1     9           26.4
## 10  2013     1    10           32.6
## # … with 355 more rows

Полезные функции

count

count() = group_by() + n()

Найдем количество перелетов за каждый день.

## # A tibble: 365 x 4
## # Groups:   year, month [12]
##     year month   day     n
##    <int> <int> <int> <int>
##  1  2013     1     1   842
##  2  2013     1     2   943
##  3  2013     1     3   914
##  4  2013     1     4   915
##  5  2013     1     5   720
##  6  2013     1     6   832
##  7  2013     1     7   933
##  8  2013     1     8   899
##  9  2013     1     9   902
## 10  2013     1    10   932
## # … with 355 more rows

Это можно было сделать короче с помощью count.

## # A tibble: 365 x 4
##     year month   day     n
##    <int> <int> <int> <int>
##  1  2013     1     1   842
##  2  2013     1     2   943
##  3  2013     1     3   914
##  4  2013     1     4   915
##  5  2013     1     5   720
##  6  2013     1     6   832
##  7  2013     1     7   933
##  8  2013     1     8   899
##  9  2013     1     9   902
## 10  2013     1    10   932
## # … with 355 more rows

В count есть аргумент sort, который может отсортировать значения по убыванию.

## # A tibble: 365 x 4
##     year month   day     n
##    <int> <int> <int> <int>
##  1  2013    11    27  1014
##  2  2013     7    11  1006
##  3  2013     7     8  1004
##  4  2013     7    10  1004
##  5  2013    12     2  1004
##  6  2013     7    18  1003
##  7  2013     7    25  1003
##  8  2013     7    12  1002
##  9  2013     7     9  1001
## 10  2013     7    17  1001
## # … with 355 more rows

В count можно передавать логическое выражение.

## # A tibble: 3 x 2
##   `dep_delay > 10`      n
##   <lgl>             <int>
## 1 FALSE            245687
## 2 TRUE              82834
## 3 NA                 8255

top_n

Функция top_n может вывести лучший результат (или результаты) по каждой группе, основываясь на какой-то переменной. Давайте посмотрим на самую большую задержку вылета за каждый день.

## # A tibble: 370 x 4
## # Groups:   year, month, day [365]
##     year month   day dep_delay
##    <int> <int> <int>     <dbl>
##  1  2013     1     1       853
##  2  2013     1     2       379
##  3  2013     1     3       291
##  4  2013     1     4       288
##  5  2013     1     5       327
##  6  2013     1     6       202
##  7  2013     1     7       366
##  8  2013     1     8       188
##  9  2013     1     9      1301
## 10  2013     1    10      1126
## # … with 360 more rows

sample_n и sample_frac

Эти функции позволяют отобрать случайные наблюдения.

## # A tibble: 10 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1  2013     3     8      921            835        46     1408
##  2  2013    12     6     1354           1400        -6     1559
##  3  2013     7    28     1025           1029        -4     1143
##  4  2013    11     7     2058           2100        -2     2209
##  5  2013    12    30     2018           2005        13     2339
##  6  2013     1    18      636            640        -4      901
##  7  2013    12    29     1212           1151        21     1517
##  8  2013     4     5     1929           1930        -1     2250
##  9  2013    10    25     1854           1900        -6     2049
## 10  2013     3    22      558            600        -2      850
## # … with 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
## #   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## #   time_hour <dttm>
## # A tibble: 3,368 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1  2013     1    25       NA           1705        NA       NA
##  2  2013    12    29     1301           1300         1     1557
##  3  2013     3     3      724            730        -6     1012
##  4  2013     7     6     1312           1310         2     1553
##  5  2013     6    21      926            929        -3     1214
##  6  2013     9    16     1532           1539        -7     1828
##  7  2013     8     2     2113           2049        24     2358
##  8  2013     3    29     1717           1719        -2     1933
##  9  2013     7    24     1015           1015         0     1206
## 10  2013    10    29      608            610        -2      723
## # … with 3,358 more rows, and 12 more variables: sched_arr_time <int>,
## #   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <dttm>

slice

Функция slice позволяет отобрать наблюдения по номеру строки, в которой они находятся. Напимер, отберем с 10 по 20 наблюдения.

## # A tibble: 11 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>
##  1  2013     1     1      558            600        -2      753
##  2  2013     1     1      558            600        -2      849
##  3  2013     1     1      558            600        -2      853
##  4  2013     1     1      558            600        -2      924
##  5  2013     1     1      558            600        -2      923
##  6  2013     1     1      559            600        -1      941
##  7  2013     1     1      559            559         0      702
##  8  2013     1     1      559            600        -1      854
##  9  2013     1     1      600            600         0      851
## 10  2013     1     1      600            600         0      837
## 11  2013     1     1      601            600         1      844
## # … with 12 more variables: sched_arr_time <int>, arr_delay <dbl>,
## #   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## #   time_hour <dttm>

distinct

Выдает датафрейм уникальных значений. Может принимать несколько переменных.

## # A tibble: 12 x 1
##    month
##    <int>
##  1     1
##  2    10
##  3    11
##  4    12
##  5     2
##  6     3
##  7     4
##  8     5
##  9     6
## 10     7
## 11     8
## 12     9
## # A tibble: 2 x 2
##   `month == 1`      n
##   <lgl>         <int>
## 1 FALSE        309772
## 2 TRUE          27004