【问题标题】:dbplyr group by dynamic variable namesdbplyr 按动态变量名分组
【发布时间】:2021-04-13 14:36:47
【问题描述】:

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

我的示例:尝试在 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    

【问题讨论】:

    标签: r dplyr dbplyr


    【解决方案1】:

    这里有两种可能的方法。

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

    【讨论】:

    • 我将采用第一种方法,因为当我有超过 1 个元素时,我无法让它与 .data[[grouping_variable]] 一起使用。但是!!!syms(grouping_variable) 可以处理多个元素。非常感谢。
    【解决方案2】:

    所以,对于 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 &lt;- sym("Species") 应该可以解决问题。

    【讨论】:

    • 这在本地 dplyr 中有效并不能保证它在 dbplyr 中有效。 dbplyr 是一种用于处理远程数据库的技术。
    • @Simon.S.A.完全正确。我不确定acrossany_of 是否与dbplyr 一起使用
    猜你喜欢
    • 1970-01-01
    • 2018-07-22
    • 2017-11-06
    • 2023-03-26
    • 1970-01-01
    • 2014-07-12
    • 2011-05-12
    • 2020-11-04
    相关资源
    最近更新 更多