Когда использовать rlang::ensym() вместо rlang::sym()?
Я могу видеть из документации, что rlang::enquo()
а также rlang::quo()
используются в разных контекстах. Следовательно, я использовал rlang::enysm()
недавно в объявлении функции (см. ниже). Однако, завернувшись в другой вызов функции SE, я получил неожиданную ошибку, которая, как мне кажется, связана с отложенной оценкой (и которая исчезнет, если я force(x)
в f_enysm()
). Но кажется, что я также могу обойти это, просто используя sym(x)
вместо ensym(x)
поскольку x
является строкой, которая не передает никакой информации об окружении (в отличие от предложений).
Это безопасно?
Если да, я не вижу, когда мне лучше ensym()
над sym
и предлагаемое использование кажется несовместимым с терминологией, используемой с quo()
/ enquo()
, expr()
/ enexpr()
и т.п.
library(rlang)
f_ensym <- function(data, x, fun) {
x <- fun(x)
head(dplyr::arrange(data, !!x))
}
f_ensym(mtcars, "cyl", sym)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> 2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#> 3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
#> 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
#> 5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
#> 6 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
f_sym <- function(data, x) {
x <- sym(x)
head(dplyr::arrange(data, !!x))
}
g <- function(data, x, fun) {
fun(data, x)
}
g(mtcars, "cyl", f_ensym)
#> Error in fun(x): argument "fun" is missing, with no default
g(mtcars, "cyl", f_sym)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> 2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#> 3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
#> 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
#> 5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
#> 6 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
# If I remove one level, I don't get the problematic behaviour.
f <- function(data, x, fun) {
x <- fun(x)
head(dplyr::arrange(data, !!x))
}
f(mtcars, "cyl", sym)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> 2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#> 3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
#> 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
#> 5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
#> 6 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
f(mtcars, "cyl", ensym)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> 2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#> 3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
#> 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
#> 5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
#> 6 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Также, если я удалю промежуточную функцию f_sym()
а также f_enysm()
и сделать прямой звонок f()
Я не понимаю проблемного поведения.
f <- function(data, x, fun) {
x <- fun(x)
head(dplyr::arrange(data, !!x))
}
f(mtcars, "cyl", sym)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> 2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#> 3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
#> 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
#> 5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
#> 6 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
f(mtcars, "cyl", ensym)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> 2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#> 3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
#> 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
#> 5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
#> 6 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
1 ответ
ensym
может принимать аргументы как в кавычках, так и без кавычек
f_ensym(mtcars, "cyl")
f_ensym(mtcars, cyl)
На основе обновленного примера в посте ОП, в то время как sym
принимает строковый объект g
принимает только три аргумента и fun
часть этого 'f_ensymwhich also have a
Веселье, которое не передается. У нас может быть еще один аргумент для этого
g <- function(data, x, fun, fun2) {
fun(data, x, fun2)
}
g(mtcars, "cyl", f_ensym, sym)
# mpg cyl disp hp drat wt qsec vs am gear carb
#1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
#4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
#5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
#6 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1