укороченный_вариант_таблицы <���– select(flights,
year:day,
ends_with("delay"),
distance,
air_time)
Теперь добавим вычисляемые поля с информацией об опоздании, – задержке вылета минус задержка прилета, в минутах, и о средней скорости полёта. Обратите внимание, что можно ссылаться на столбцы, которые уже созданы. Если вдруг захотите сохранить только новые переменные, то используйте transmute() вместо mutate():
mutate(укороченный_вариант_таблицы,
опоздание = dep_delay – arr_delay,
скорость = distance / air_time * 60,
часы_полёта= air_time / 60,
опоздание_в_каждом_часе = опоздание / часы_полёта )
Существует много функций для создания новых переменных, которые можно комбинировать с mutate(). Ключевое их свойство заключается в том, что функция должна быть пригодной для обработки векторов, то есть она должна принимать вектор значений на входе и возвращать вектор с тем же количеством значений на выходе. Нет возможности перечислить все такие функции, но приведём некоторые из реально используемых.
Арифметические операторы: +, -, *, /, ^. Все они работают с векторами используя так называемые «правила рециркуляции», заключающиеся в том, что если один параметр короче другого, то произойдет автоматическое удлинение до равного размера путём клонирования короткого вектора достаточное количество раз. Это полезно, когда один из аргументов – число. В примере выше так были вычислены часы_полёта делением вектора на скаляр, а скорость умножением вектора на скаляр. Арифметические операторы также полезны в связке с агрегирующими функциями, о которых узнаете позже. Например, x / sum(x) вычисляет долю от общей суммы значений переменной, а y – mean(y) вычисляет отклонение величины от среднего.
Модулярная арифметика: %/% (целочисленное деление) и %% (остаток), здесь x == y * (x %/% y) + (x %% y). Модулярная арифметика очень удобный инструмент, потому что позволяет представлять большие целые числа сравнительно небольшими остатками. Например, в наборе данных flights можно выделить полные часы и оставшиеся минуты из общей продолжительности полёта, представленной в формате ЧЧММ или ЧММ (dep_time). Тогда вместо хранения и выполнения различных операций над одним большим числом, можно будет хранить и выполнять операции над двумя маленькими:
transmute(flights,
dep_time,
час = dep_time %/% 100,
минута = dep_time %% 100)
Логарифмические функции: log(), log2(), log10(), являются невероятно полезным преобразованием при работе с данными, диапазон которых охватывает несколько порядков наблюдаемой величины. Они также преобразуют мультипликативные операции в аддитивные, к этой особенности вернемся в разделе, посвященном моделированию. При прочих равных условиях, рекомендуется использовать функцию log2() так как её значения легко интерпретировать: разница в 1 на логарифмической линейке соответствует удвоению в исходном масштабе, а разница в -1 соответствует делению пополам.
Смещения: вперёд lead() и назад lag() позволяют просматривать последующие и предыдущие значения списка. Бывают необходимо вычислить приращение аргумента, например, х – lag(x), или проверить неизменность его значений, выражением x != lag(x). Смещения особенно полезны в сочетании с group_by(), но не будем забегать вперёд.
Накопительные и скользящие агрегаторы: R предоставляет функции для вычисления накапливаемой суммы cumsum(), произведения cumprod(), минимума cummin() и максимума cummax() элементов списка; кроме того, dplyr имеет функцию cummean() для вычисления среднего значения. Если нужны скользящие агрегаторы, когда сумма вычисляется по скользящему окну, то обращаются к функционалу пакета RcppRoll.
Логические сравнения: < (меньше), <= (не больше), > (больше), >= (не меньше), != (не равны), и == (равны), о них мы узнали ранее. Напомню лишь, если осуществляется сложная последовательность логических операций, то настоятельно рекомендуется сохранять промежуточные значения в отдельных вспомогательных переменных, чтобы проверить значение выражения на каждом шаге вычислений.
Ранжирование: объединяет в себе целый ряд функций, начиная с min_rank(), которая осуществляет вычисление простого порядкового номера (например, 1-й, 2-й, 3-й, 4-й). По умолчанию присваиваются меньшие номера меньшим значениям, но можно воспользоваться функцией desc() для обращения порядка значений аргумента, чтобы придать наибольшие порядковым номера наименьшим значениям элементов исходного списка. Если min_rank() не делает то, что нужно, загляните в описание функций ранжирования на страницах справки для получения более подробной информации.
Читать дальше