Для простых уравнений, которые принимают один вход, достаточно указать саму функцию, например,
iris %>% mutate_at(vars(-Species), sqrt)
Или, при использовании уравнения, а не простой функции, по формуле:
iris %>% mutate_at(vars(-Species), ~ . ^ 2)
При использовании уравнений, которые обращаются более чем к одной переменной, вам нужно использовать вместо этого выражения rlang:
area = quo(Sepal.Length * Sepal.Width)
iris %>% mutate(Sepal.Area = !! area)
Здесь quo
создает «quosure» -т. е. представление вашего уравнения в кавычках, такое же, как вы используете строки, за исключением того, что, в отличие от строк, оно правильно определено, непосредственно используется dplyr и концептуально чище: оно подобно любому другому выражению R, за исключением того, что еще не вычислено.Разница заключается в следующем:
1 + 2
- это выражение со значением 3
. quo(1 + 2)
- это неоцененное выражение со значением 1 + 2
, которое оцениваетдо 3
, но это должно быть явно оценено.Так как же мы оценили неоцененное выражение?Ну…:
Затем !!
(произносится «bang bang») снимает кавычки ранее цитируемое выражение, т.е. оценивает его - внутриконтекст mutate
.Это важно, потому что Sepal.Length
и Sepal.Width
известны только внутри вызова mutate
, а не за его пределами.
Во всех вышеупомянутых случаях выражения могут быть внутри списка,тоже.Единственное отличие состоит в том, что для списков нужно использовать !!!
вместо !!
:
funs = list(
Sepal.Area = quo(Sepal.Length * Sepal.Width),
Sepal.Ratio = quo(Sepal.Length / Sepal.Width)
)
iris %>% mutate(!!! funs)
Операция !!!
известна как «unquote-splice».Идея состоит в том, что он «склеивает» элементы списка своих аргументов в родительский вызов.То есть кажется, что он изменяет вызов так, как если бы он содержал дословно элементы списка в качестве аргументов (хотя это работает только в функциях, таких как mutate
, которые его поддерживают).