group_by 使用 tidyeval 的非标量字符向量
group_by with non-scalar character vectors using tidyeval
使用 R 3.2.2 和 dplyr 0.7.2 我想知道如何有效地使用 group_by
以字符向量形式提供的字段。
选择很容易,我可以 select 通过字符串这样的字段
(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
等各种组合并保存它们在中间变量中,因为这有时似乎有所作为,但无法使其发挥作用。
select()
在dplyr中很特别。它不接受 columns,但接受 names 或 positions 列。所以这是唯一接受字符串的主要动词。 (从技术上讲,当您向 select 提供像 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")
要调试取消引用,用 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"))
使用 R 3.2.2 和 dplyr 0.7.2 我想知道如何有效地使用 group_by
以字符向量形式提供的字段。
选择很容易,我可以 select 通过字符串这样的字段
(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
等各种组合并保存它们在中间变量中,因为这有时似乎有所作为,但无法使其发挥作用。
select()
在dplyr中很特别。它不接受 columns,但接受 names 或 positions 列。所以这是唯一接受字符串的主要动词。 (从技术上讲,当您向 select 提供像 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")
要调试取消引用,用 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"))