了解何时在函数中使用 ensym、sym 与 enquo

Jma*_*mac 9 r ggplot2 dplyr nse rlang

我正在尝试了解不同的 quo/unquo 语法以及何时应该使用它们。

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

根据我所读到的内容,我的理解是:

1)如果我引用数据框中的列,那么我不需要捕获环境,我可以使用ensymor sym它是否正确?使用 会出现问题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")

Run Code Online (Sandbox Code Playgroud)

如何将裸列参数或符号转换为字符串以在上面 myfun 的最后一行中使用? 我尝试过rlang::as_string(!!ensym(xvar)),但没有成功。

Art*_*lov 5

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

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

median(dat[[deparse(ensym(xvar))]])
Run Code Online (Sandbox Code Playgroud)

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

median(dat[[rlang::as_string(ensym(xvar))]])
Run Code Online (Sandbox Code Playgroud)