如何解决R dplyr:当...将在数据中引用变量名称时,如何将...与summaryacross结合使用?
我希望使用summarize
具有灵活的功能,其中:
- 聚合功能由用户提供
- 聚合函数可能会使用其他参数,这些参数引用数据本身中的变量。
一个很好的例子是用户提供fun=weighted.mean()
并指定权重参数w
。
目前,我正在尝试使用...
。问题是我找不到让...
引用数据帧内变量的方法吗?下面的示例使用across()
给出,但是如果我改用summarize_at()
谢谢!
library(tidyverse)
fo1 <- function(df,fun=mean,...){
df %>%
group_by(Species) %>%
summarise(across(starts_with("sepal"),fun,...))
}
fo1(iris)
#> `summarise()` ungrouping output (override with `.groups` argument)
#> # A tibble: 3 x 3
#> Species Sepal.Length Sepal.Width
#> <fct> <dbl> <dbl>
#> 1 setosa 5.01 3.43
#> 2 versicolor 5.94 2.77
#> 3 virginica 6.59 2.97
fo1(iris,fun=weighted.mean)
#> `summarise()` ungrouping output (override with `.groups` argument)
#> # A tibble: 3 x 3
#> Species Sepal.Length Sepal.Width
#> <fct> <dbl> <dbl>
#> 1 setosa 5.01 3.43
#> 2 versicolor 5.94 2.77
#> 3 virginica 6.59 2.97
fo1(iris,fun=weighted.mean,w=Petal.Length)
#> Error: Problem with `summarise()` input `..1`.
#> x object 'Petal.Length' not found
#> ℹ Input `..1` is `across(starts_with("sepal"),...)`.
#> ℹ The error occurred in group 1: Species = "setosa".
fo1(iris,w=.data$Petal.Length)
#> Error: Problem with `summarise()` input `..1`.
#> x 'x' and 'w' must have the same length
#> ℹ Input `..1` is `across(starts_with("sepal"),...)`.
#> ℹ The error occurred in group 1: Species = "setosa".
由reprex package(v0.3.0)于2020-11-10创建
解决方法
您需要传递其他参数的确切值。 .data$Petal.Length
是NULL
。
library(dplyr)
fo1 <- function(df,fun=mean,...){
df %>%
summarise(across(starts_with("sepal"),fun,...))
}
fo1(iris,fun=weighted.mean,w= iris$Petal.Length)
# Sepal.Length Sepal.Width
#1 6.180167 2.970197
,
这很丑,但是行得通。
> fo1 <- function(df,...){
+ w <- df %>% pull(...)
+ df %>%
+ summarise(across(starts_with("Sepal"),w))
+ }
> fo1(iris,Petal.Length)
Sepal.Length Sepal.Width
1 6.180167 2.970197
根据上述评论中Paul的建议,这似乎是一个普遍的解决方案:
fo1 <- function(df,...){
df %>%
summarise(across(starts_with("Sepal"),!!!enquos(...)))
}
> fo1(iris,Petal.Length)
Sepal.Length Sepal.Width
1 6.180167 2.970197
> fo1(iris,fun=mean)
Sepal.Length Sepal.Width
1 5.843333 3.057333
我尝试了!!
,!!!
,enquo()
和enquos()
的几种组合,但肯定错过了。
enquos
将返回一个带引号的表达式列表。 unquote-splice运算符!!!
将取消引用每个元素作为函数调用的参数。
library(tidyverse)
fo1 <- function(df,fun = mean,...) {
df %>%
summarise(across(starts_with("sepal"),!!!enquos(...)))
}
iris %>%
group_by(Species) %>%
fo1(fun = weighted.mean,w = Petal.Length,na.rm = TRUE)
#> # A tibble: 3 x 3
#> Species Sepal.Length Sepal.Width
#> <fct> <dbl> <dbl>
#> 1 setosa 5.02 3.44
#> 2 versicolor 5.98 2.79
#> 3 virginica 6.64 2.99
有关更多信息,请参见here。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。