Конструкция ~./sum(x)
технически представляет собой особый тип объекта R, называемый формулой
class(~./sum(x))
#> [1] "formula"
Однако в функциях tidyverse, таких как mutate_all
, эта формула используется и преобразован в лямбда-функцию , которая является анонимной функцией (то есть функцией, которая не имеет имени и записывается на месте как параметр, передаваемый при вызове другой функции).
Внутренне формула преобразуется в функцию с rlang::as_function
. Предположим, мы хотим написать функцию, которая просто добавляет два к переменной. В базе R мы могли бы написать
add_two <- function(var){
return(var + 2)
}
add_two(5)
#> [1] 7
В тидиверсе мы можем использовать формулу как сокращение для этой функции, где .
становится сокращением для «переменной, которая была передана в качестве первого аргумента в функция ":
add_two <- rlang::as_function(~ . + 2)
add_two(5)
#> [1] 7
В таких функциях, как mutate_all
, формула будет автоматически передаваться через rlang::as_function
, поэтому, если бы мы хотели добавить два в каждый столбец в нашем фрейме данных, вместо того, чтобы писать :
mutate_all(.funs= function(var) {return(var + 2);})
мы могли бы написать
mutate_all(.funs=~.+2)
В вашем случае формула ~./sum(x)
фактически преобразуется в
function(var) {
return(var / sum(x))
}
, где x должен существовать либо как столбец в вашем фрейме данных или переменная в вызывающей среде.
Причины использования этого способа в том, что он экономит ввод и сокращает строки кода. Вставка функции в вызов другой функции часто приводит к запутанному и плохо отформатированному коду. Этот сокращенный метод помогает предотвратить это.
Подробнее об анонимных функциях и их использовании в tidyverse можно прочитать здесь