【问题标题】:Understanding when to use ensym, sym vs enquo in a function了解何时在函数中使用 ensym、sym 与 enquo
【发布时间】:2020-05-13 04:39:56
【问题描述】:

我试图围绕不同的 quo/unquo 语法以及何时应该使用每种语法。

我主要编写传递数据框和列以用作参数的函数——使用 ggplot 绘图或使用 dplyr(group_by、summary、mutate 等)汇总/操作数据。但是,有时我还必须在我的整体功能中使用不使用 NSE 的功能。

根据我的阅读,我的理解是:

1) 如果我引用数据框中的列,那么我不需要捕获环境,我可以使用ensymsym这是正确的吗?使用enquo 会不会有问题,还是没有必要?

2) 如果我使用ensym,用户可以在技术上在参数中输入字符串或裸列名称。

基于此,我的典型功能设置如下所示:

library(tidyverse)

dataset <- mtcars

myfun <- function(dat, xvar, yvar, group){

  #either manipulate data
  x <- dat %>% group_by(!!ensym(group)) %>%
    mutate(new = !!ensym(xvar)*5) %>%
    summarize(medianx=median(!!ensym(xvar), na.rm=TRUE), 
              median_new=median(new, na.rm=TRUE))


  #or plot data
  p <- ggplot(dat, aes(x=!!ensym(xvar), y=!!ensym(yvar))) + 
    geom_point()

  #sometime require referencing the column with NSE function..
  median(dat[[xvar]])  #works if require string in argument

  #how would you reference this with bare argument column? Convert ensym to string?
  median(dat[[?????]])
}

#both work with ensym, only the later with sym
myfun(dataset, xvar=mpg, yvar=disp, group=cyl)
myfun(dataset, xvar="mpg", yvar="disp", group="cyl")

如何将裸列参数或符号转换为字符串以供上面 myfun 的最后一行使用?我试过 rlang::as_string(!!ensym(xvar)),但它不起作用。

【问题讨论】:

  • 您是否尝试过 {{}} 表示法 - 例如 stackoverflow.com/questions/56926211/…
  • @RichardTelford 我认为 (?) {{}} 替换了 !!enquo() 因此,如果参数输入为裸露(未引用),它将在 dplyr 管道中工作。不确定它对于不使用 NSE 的函数如何工作。

标签: r ggplot2 dplyr rlang nse


【解决方案1】:

你的理解是正确的。在引用现有数据框中的列时,首选sym/ensymenquo() 当然也可以,但它可以捕获任意表达式,允许用户指定 mpg * cyllog10(mpg + cyl)/2 之类的内容。如果您的下游代码假定 xvaryvar 是单列,则使用任意表达式可能会导致问题或意外行为。从这个意义上说,ensym() 在您期望引用单个列时执行参数验证步骤。

至于将符号转换为字符串,一种方法是使用deparse()

median(dat[[deparse(ensym(xvar))]])

要使rlang::as_string 工作,您需要删除!!,因为您希望将表达式本身转换为字符串,而不是表达式所指的内容(例如,mpgcyl 等.):

median(dat[[rlang::as_string(ensym(xvar))]])

【讨论】:

    猜你喜欢
    • 2018-08-18
    • 2020-01-17
    • 1970-01-01
    • 2019-12-11
    • 2018-05-11
    • 1970-01-01
    • 2023-01-26
    • 2019-01-24
    • 2019-10-28
    相关资源
    最近更新 更多