r - 将多个调用参数传递给 dplyr 自定义函数中的形式参数,而不使用“...”
问题描述
为了使自定义函数能够灵活地接收每个形式参数的一个或多个调用参数,我目前依赖“...”:
library(dplyr)
foo <- function(data, ..., dv){
groups <- enquos(...)
dv <- enquo(dv)
data %>%
group_by(!!!groups) %>%
summarise(group_mean = mean(!!dv))
}
mtcars %>% foo(am, dv = mpg)
mtcars %>% foo(vs, am, dv = mpg)
但是“...”模糊了函数的逻辑,并且它不能用于具有 2 个或多个需要多个调用参数的正式参数的自定义函数。
有没有办法编写上述函数来利用形式参数(例如,“组”)而不是“...”,它可以接收单个向量名称或向量名称的向量作为其参数?就像是:
foo <- function(data, groups, dv){
groups <- enquos(groups)
dv <- enquo(dv)
data %>%
group_by(!!!groups) %>%
summarise(group_mean = mean(!!dv))
}
# Failing code
mtcars %>% foo(groups = c(vs, am), dv = mpg)
请注意,此代码可以工作,但需要用户记住在函数体中使用 quos():
foo <- function(data, groups, dv){
dv <- enquo(dv)
data %>%
group_by(!!!groups) %>%
summarise(group_mean = mean(!!dv))
}
mtcars %>% foo(groups = quos(vs, am), dv = mpg)
我很想在函数体中依赖 enquos() 。
解决方案
我们可以...
把
foo <- function(data, dv, ...){
groups <- enquos(...)
dv <- enquo(dv)
data %>%
group_by(!!!groups) %>%
summarise(group_mean = mean(!!dv))
}
如果我们想传递一个vector
“组”,那么一个选项是group_by_at
foo <- function(data, groups, dv){
dv <- enquo(dv)
data %>%
group_by_at(vars(groups)) %>%
summarise(group_mean = mean(!!dv))
}
mtcars %>%
foo(groups = c("vs", "am"), dv = mpg)
# A tibble: 4 x 3
# Groups: vs [?]
# vs am group_mean
# <dbl> <dbl> <dbl>
#1 0 0 15.0
#2 0 1 19.8
#3 1 0 20.7
#4 1 1 28.4
如果我们想传递不带引号的表达式,一种选择c
是将其转换为表达式,然后对其求值
foo <- function(data, groups, dv){
groups <- as.list(rlang::enexpr(groups))[-1]
dv <- enquo(dv)
data %>%
group_by(!!! groups) %>%
summarise(group_mean = mean(!!dv))
}
mtcars %>%
foo(groups = c(vs, am), dv = mpg)
# A tibble: 4 x 3
# Groups: vs [?]
# vs am group_mean
# <dbl> <dbl> <dbl>
#1 0 0 15.0
#2 0 1 19.8
#3 1 0 20.7
#4 1 1 28.4
或者正如评论中提到的@Joe,enquo
也应该与group_by_at
foo <- function(data, groups, dv){
dv <- enquo(dv)
groups <- enquos(groups)
data %>%
group_by_at(vars(!!!groups)) %>%
summarise(group_mean = mean(!!dv))
}
mtcars %>%
foo(groups = c(vs, am), dv = mpg)
# A tibble: 4 x 3
# Groups: vs [?]
# vs am group_mean
# <dbl> <dbl> <dbl>
#1 0 0 15.0
#2 0 1 19.8
#3 1 0 20.7
#4 1 1 28.4
推荐阅读
- docker - 如何手动运行 cron 作业并检查 ubuntu 中的日志
- r - ggplot R中的X轴子标签
- angular - 轮询:页面被刷新,任何指定的过滤器/排序顺序也被重置。我怎样才能防止这种情况发生?
- html - 无法在 CSS 中更改 Google 字体粗细
- visual-studio-code - 如何将ssh密码保存到vscode?
- strapi - 如何自定义 Strapi WYIWYG 内容编辑器?
- pandas - 过滤熊猫中小于某个值的负值
- javascript - 在 JavaScript 中使用媒体查询或在 CSS 中使用 if/else 语句
- flutter - 如何使用 getit 包监听扩展 changeNotifer 的单例类的变化?
- analytics - 我怎样才能得到谷歌分析网站css、js