问题描述
如何使用动态变量名称进行分组?
我的例子:尝试在 Species
列上分组,知道它在 grouping_variable
变量中吗?
library(dplyr)
library(dbplyr)
library(DBI)
# My table
iris_table <- tbl(src = my_db_conn,in_schema(schema = "my_schema",table = "iris_table"))
# The grouping variable
grouping_variable <- "Species"
# My tries
iris_table %>%
group_by(across(any_of(grouping_variable))) %>%
summarise(sum_petal_length = sum(Petal.Length))
### ==> returns error
iris_table %>%
group_by(!!!grouping_variable) %>%
summarise(sum_petal_length = sum(Petal.Length))
### ==> returns grouping by the character "Species"
我的sessionInfo()
:
attached base packages:
[1] stats graphics Grdevices utils datasets methods base
other attached packages:
[1] DBI_1.1.0 dbplyr_1.4.4 dplyr_1.0.0 lubridate_1.7.9
loaded via a namespace (and not attached):
[1] Rcpp_1.0.5 rstudioapi_0.11 magrittr_1.5 hms_0.5.3 odbc_1.3.0 tidyselect_1.1.0
[7] bit_1.1-15.2 R6_2.4.1 rlang_0.4.7 fansi_0.4.1 blob_1.2.1 tools_3.6.2
[13] utf8_1.1.4 cli_2.0.2 ellipsis_0.3.1 readxl_1.3.1 bit64_0.9-7.1 assertthat_0.2.1
[19] tibble_3.0.3 lifecycle_0.2.0 Crayon_1.3.4 zip_2.0.4 purrr_0.3.4 tidyr_1.1.0
[25] vctrs_0.3.2 glue_1.4.1 openxlsx_4.1.5 stringi_1.4.6 cellranger_1.1.0 compiler_3.6.2
[31] pillar_1.4.6 generics_0.0.2 pkgconfig_2.0.3
解决方法
这里有两种可能的方法。
(1) 与您已经使用的方法最相似,我们首先必须告诉 R 字符串应该被视为符号:
iris_table %>%
group_by(!!!syms(grouping_variable)) %>%
summarise(sum_petal_length = sum(Petal.Length))
注意 syms
之前的 !!!
。这种方法使用了 rlang 包的一些特性,这些特性在其他上下文中很有用。但是,它不再是推荐的使用 dplyr 编程的方法。
(2)推荐的这种programming with dplyr方法是:
iris_table %>%
group_by(.data[[grouping_variable]]) %>%
summarise(sum_petal_length = sum(Petal.Length))
使用 dbplyr 时,这两种方法都会为您提供正确的 SQL 转换:
data(iris)
iris_table = tbl_lazy(iris,con = simulate_mssql())
# The grouping variable
grouping_variable <- "Species"
# approach 1
iris_table %>%
group_by(!!!syms(grouping_variable)) %>%
summarise(sum_petal_length = sum(Petal.Length))
# translation from approach 1
# <SQL>
# SELECT `Species`,SUM(`Petal.Length`) AS `sum_petal_length`
# FROM `df`
# GROUP BY `Species`
# approach 2
iris_table %>%
group_by(.data[[grouping_variable]]) %>%
summarise(sum_petal_length = sum(Petal.Length))
# translation from approach 2
# <SQL>
# SELECT `Species`,SUM(`Petal.Length`) AS `sum_petal_length`
# FROM `df`
# GROUP BY `Species`
,
因此,对于 dplyr 1.0.3 版,它运行良好。
grouping_variable <- "Species"
data("iris")
iris_table <- as_tibble(iris) %>%
group_by(across(any_of(grouping_variable))) %>%
summarise(sum_petal_length = sum(Petal.Length))
> iris_table
# A tibble: 3 x 2
Species sum_petal_length
* <fct> <dbl>
1 setosa 73.1
2 versicolor 213
3 virginica 278.
packageVersion("dplyr")
#> [1] '1.0.3'
据我所知,在较旧的 dplyr 版本中,grouping_variable <- sym("Species")
应该可以解决问题。