是否可以在字符向量上使用ensyms?

时间:2019-02-01 20:36:03

标签: r rlang tidyeval

在以下示例中,为什么会出现错误或意外 使用ensyms接受字符向量参数的结果? 我意识到这个特定的例子很愚蠢: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”,并且不执行构面。有没有一种方法可以使用ensym而不用省略号作为参数,这是我最熟悉的用法?

1 个答案:

答案 0 :(得分: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")