使用 purrr 和 dplyr: 是 rlang::sym 最好的方法
Using purrr and dplyr: is rlang::sym the best way
我想编写使用 dplyr 动词的函数,这意味着我必须涉足 rlang
.
的浑水
举个具体的例子,假设我想用purrr::map_df()
来遍历dplyr::group_by()
中的变量。 programming with dplyr 小插图介绍了如何编写 my_summarise()
函数;方法是在分组变量上使用 rlang::enquo()
,然后用 !!
取消引号。
这种方法可以创建一个新的类似 dplyr 的函数,该函数采用不带引号的变量名(小插图中的 my_summarise(df, g1)
)。
相比之下,我想 purrr 以字符串形式提供变量名。 rlang::sym()
是正确的方法吗?似乎不是,因为 sym()
在 dplyr 编程插图中没有提到,在 rlang tidy evaluation article 中也几乎没有提到。有没有更好的方法?
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
作为后续行动,为什么有时简单地取消引用(不首先应用 enquo
或 sym
)会起作用?在下面的示例中,为什么 select()
按预期工作但 group_by()
不工作?
x <- "cyl"
select(mtcars, !!x)
group_by(mtcars, !!x)
更新:答案与取消引用无关。就是select
比较灵活,可以处理字符串,而group_by
不能。
其他参考:此 blog post 作者:Edwin Thoen。
简答:是。
如果您想 map
遍历列,sym
是一个很好的方法。 Lionel Henry 在 draft vignette.
中展示了 sym
如果您想传递列名,但又不想迭代,Kirill Müller prefers quo
。在下面的示例中,它们具有相同的效果。
library(dplyr)
x <- rlang::quo(cyl)
y <- rlang::sym("cyl")
identical(group_by(mtcars, !!x), group_by(mtcars, !!y)) # TRUE
我想编写使用 dplyr 动词的函数,这意味着我必须涉足 rlang
.
举个具体的例子,假设我想用purrr::map_df()
来遍历dplyr::group_by()
中的变量。 programming with dplyr 小插图介绍了如何编写 my_summarise()
函数;方法是在分组变量上使用 rlang::enquo()
,然后用 !!
取消引号。
这种方法可以创建一个新的类似 dplyr 的函数,该函数采用不带引号的变量名(小插图中的 my_summarise(df, g1)
)。
相比之下,我想 purrr 以字符串形式提供变量名。 rlang::sym()
是正确的方法吗?似乎不是,因为 sym()
在 dplyr 编程插图中没有提到,在 rlang tidy evaluation article 中也几乎没有提到。有没有更好的方法?
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
作为后续行动,为什么有时简单地取消引用(不首先应用 enquo
或 sym
)会起作用?在下面的示例中,为什么 select()
按预期工作但 group_by()
不工作?
x <- "cyl"
select(mtcars, !!x)
group_by(mtcars, !!x)
更新:答案与取消引用无关。就是select
比较灵活,可以处理字符串,而group_by
不能。
其他参考:此 blog post 作者:Edwin Thoen。
简答:是。
如果您想 map
遍历列,sym
是一个很好的方法。 Lionel Henry 在 draft vignette.
sym
如果您想传递列名,但又不想迭代,Kirill Müller prefers quo
。在下面的示例中,它们具有相同的效果。
library(dplyr)
x <- rlang::quo(cyl)
y <- rlang::sym("cyl")
identical(group_by(mtcars, !!x), group_by(mtcars, !!y)) # TRUE