4. Является ли результатом выполнения следующего кода неожиданным? Что вспомогательные функции выбора переменных в нём возвращают по умолчанию? Как изменить их значение по умолчанию?

select(flights, -contains("TIME"))

Помимо выборки существующих столбцов, полей таблицы базы данных, переменных, бывает необходимым добавление новых столбцов, которые хранят значения, являющиеся функциями от существующих. Это выполняется путём обращения к функции mutate(), которая всегда добавляет новые столбцы в конце имеющегося набор данных. Поэтому создадим более узкий набор данных, чтобы видеть новые переменные. Помните, что в RStudio самый простой способ увидеть все столбцы таблицы это вызов функции view(). Создадим укороченный_вариант_таблицы, содержащий все поля между «год» (year) и «день» (day) включительно, плюс поля, содержащие информацию о задержках (заканчивающиеся на delay), покрытом расстоянии (distance) и времени полёта (air_time) в минутах:

укороченный_вариант_таблицы <– 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 соответствует делению пополам.