使用purrr和dplyr:rlang::sym是最好的方法吗

使用purrr和dplyr:rlang::sym是最好的方法吗,r,dplyr,purrr,rlang,R,Dplyr,Purrr,Rlang,我想编写使用dplyr动词的函数,这意味着我必须涉入rlang的黑暗水域 为了提供一个具体的例子,假设我想使用purrr::map_df()在dplyr::group_by()中迭代变量。vignette完成了编写my_summary()函数的过程;这里的方法是在分组变量上使用rlang::enquo(),然后使用取消引用。 这种方法可以创建一个新的类似dplyr的函数,该函数采用不带引号的变量名(my_summary(df,g1),在vignette中) 相反,我希望以字符串形式提供变量名。r

我想编写使用dplyr动词的函数,这意味着我必须涉入
rlang
的黑暗水域

为了提供一个具体的例子,假设我想使用
purrr::map_df()
dplyr::group_by()
中迭代变量。vignette完成了编写
my_summary()
函数的过程;这里的方法是在分组变量上使用
rlang::enquo()
,然后使用
取消引用。
这种方法可以创建一个新的类似dplyr的函数,该函数采用不带引号的变量名(
my_summary(df,g1)
,在vignette中)

相反,我希望以字符串形式提供变量名。
rlang::sym()
这样做正确吗?似乎不是,因为dplyr编程小插曲中没有提到
sym()
,rlang中也几乎没有提到。有更好的办法吗

library(tidyverse)
my_summarise <- function(df, group_var) {
  group_var <- rlang::sym(group_var)

  df %>%
    group_by(!!group_var) %>%
    summarise(mpg = mean(mpg))
}

# This works. Is that a good thing?
purrr::map_df(c("cyl", "am"), my_summarise, df = mtcars)

# A tibble: 5 x 3
    cyl   mpg    am
  <dbl> <dbl> <dbl>
1  4.00  26.7 NA   
2  6.00  19.7 NA   
3  8.00  15.1 NA   
4 NA     17.1  0   
5 NA     24.4  1.00
更新:答案不是关于取消引用。这是因为
select
更灵活,可以处理字符串,而
groupby
则不能

其他参考:这是Edwin Theon写的。

简短回答:是的

如果要在列上映射
sym
是一种很好的方法。莱昂内尔·亨利(Lionel Henry)在舞台上演示了
sym

如果您想传递列名,但不想进行迭代,请使用Kirill Müller
quo
。在下面的示例中,它们具有相同的效果

library(dplyr)

x <- rlang::quo(cyl)
y <- rlang::sym("cyl")
identical(group_by(mtcars, !!x), group_by(mtcars, !!y))  # TRUE
库(dplyr)

我要说的是,最近,使用sym()解决了我在引用中所有看似无法解决的问题。有时
!!sym()
尤其是当有表达式时。此外,我认为最好将其分为两个问题。小插曲草稿确实使用了
sym
。谢谢你们两位,@Elin和@G-Grothendieck!随着rlang>=0.4.0,这变得更容易了。如果
x
是字符串,则使用
groupby(.data[[x]])
library(dplyr)

x <- rlang::quo(cyl)
y <- rlang::sym("cyl")
identical(group_by(mtcars, !!x), group_by(mtcars, !!y))  # TRUE