Можно ли использовать энзимы на символьном векторе?
В следующем примере, почему я получаю ошибку или неожиданные результаты от использования энсимов для получения аргумента векторного символа? Я понимаю, что этот конкретный пример глуп: facet_grid() может фактически использовать символьный вектор в качестве аргумента. Тем не менее, я хочу понять, как использовать sym, ensym, syms и ensyms с уверенностью, в более общем смысле.
Я написал небольшой фрагмент кода, который обрабатывает график, созданный в ggplot, через символьный вектор.
library(rlang)
library(ggplot2)
n <- 100
x1 <- rnorm(n)
x2 <- rnorm(n)
c1 <- rbinom(n, 1, .5)
c2 <- rbinom(n, 1, .5)
df_ex <- data.frame(x1=x1, x2=x2, c1=c1, c2=c2)
plot_test <- function(dat, facet_vars){
facet_vars <- ensyms(facet_vars)
p <- ggplot(dat, aes(x1,x2)) + facet_grid(vars(!!!facet_vars))
}
facet_vars <- c("c1", "c2")
#throws error
p <- plot_test(df_ex, c("c1", "c2"))
#seems to look for variable `facet_var`
p <- plot_test(df_ex, facet_vars)
Если символьный вектор непосредственно вводится в функцию, я получаю сообщение об ошибке "Ошибка: необходимо указать символы или строки в качестве аргумента". Если я ввожу facet_vars, ensyms, кажется, буквально возвращает "facet_vars", и огранка не выполняется. Есть ли способ использовать энзимы, не используя аргументы из многоточия, какое использование мне наиболее знакомо?
1 ответ
Ты используешь ensym
если вы хотите передать символ или строку в вашу функцию через нестандартную оценку. Это не то, что вы делаете с c("c1", "c2")
, Это не векторный литерал в R. Здесь вы вызываете функцию c()
с двумя параметрами, чтобы вернуть вектор. Это не простая строчка; это вызов функции. Вместо этого, если вы хотите превратить вектор строк в символы, просто используйте syms()
, Это будет работать:
plot_test <- function(dat, facet_vars){
facet_vars <- syms(facet_vars)
p <- ggplot(dat, aes(x1,x2)) + facet_grid(vars(!!!facet_vars))
}
facet_vars <- c("c1", "c2")
plot_test(df_ex, c("c1", "c2"))
plot_test(df_ex, facet_vars)
или, альтернативно, захватить его как выражение
plot_test <- function(dat, facet_vars){
facet_vars <- enexprs(facet_vars)
p <- ggplot(dat, aes(x1,x2)) + facet_grid(vars(!!!facet_vars))
}
ensyms()
работает лучше, если вы передаете строки как отдельные параметры
plot_test <- function(dat, ...){
facet_vars <- ensyms(...)
p <- ggplot(dat, aes(x1,x2)) + facet_grid(vars(!!!facet_vars))
}
plot_test(df_ex, "c1", "c2")