dbplyr 按动态变量名称分组

dbplyr group by dynamic variable names

如何使用动态变量名称进行分组?

我的示例:尝试对 Species 列进行分组,知道它在 grouping_variable var ?

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    

因此,对于 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") 应该可以解决问题。

这里有两种可能的方法。

(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`