使用 R 3.2.2 和 dplyr 0.7.2 我试图弄清楚如何有效地使用group_by
字段作为字符提供载体
选择很简单我可以通过像这样的字符串选择字段
(function(field) {
mpg %>% dplyr::select(field)
})("cyl")
通过多个字符串的多个字段,如
(function(...) {
mpg %>% dplyr::select(!!!quos(...))
})("cyl", "hwy")
和多个字段通过长度为>的一个字符向量1喜欢这个
(function(fields) {
mpg %>% dplyr::select(fields)
})(c("cyl", "hwy"))
使用group_by
我无法真正找到一种方法来为多个字符串执行此操作,因为如果我设法获得输出,它最终会按我提供的字符串进行分组。
我设法按这样的字符串分组
(function(field) {
mpg %>% group_by(!!field := .data[[field]]) %>% tally()
})("cyl")
这已经很难看了。
有谁知道我要写什么,所以我可以运行
(function(field) {...})("cyl", "hwy")
和
(function(field) {...})(c("cyl", "hwy"))
分别?我尝试了!!
,!!!
,UQ
,enquo
,quos
,unlist
等各种组合...并保存它们在中间变量中,因为这有时似乎有所不同,但却无法使其发挥作用。
答案 0 :(得分:3)
select()
在dplyr中非常特殊。它不接受列,但列名称或位置。所以这是唯一接受字符串的主要动词。 (从技术上讲,当您提供像cyl
这样的名称来进行选择时,它实际上会被评估为自己的名称,而不是数据框内的向量。)
如果您希望函数采用简单的字符串,而不是裸表达式或符号,则不需要使用quosures。只需从字符串中创建符号并取消引用它们:
myselect <- function(...) {
syms <- syms(list(...))
select(mtcars, !!! syms)
}
mygroup <- function(...) {
syms <- syms(list(...))
group_by(mtcars, !!! syms)
}
myselect("cyl", "disp")
mygroup("cyl", "disp")
要调试unquoting,请使用expr()
换行并检查表达式是否正确:
syms <- syms(list("cyl", "disp"))
expr(group_by(mtcars, !!! syms))
#> group_by(mtcars, cyl, disp) # yup, looks right!
有关详细信息,请参阅此演讲(我们将更新编程小插图以使概念更清晰):https://schd.ws/hosted_files/user2017/43/tidyeval-user.pdf。
最后,请注意,许多动词都有一个_at
后缀变体,可以毫不费力地接受字符串和字符向量:
group_by_at(mtcars, c("cyl", "disp"))