dplyr 和 postgresql 得到 group_indices

dplyr & postgresql get group_indices

我未能找到此任务的解决方案:

对于简单的情况,我们以 mtcars 为例,并使用相同数据的 PostgreSQL 版本:

library(RPostgreSQL)
library(DBI)
library(tidyverse)

pgdrv <- dbDriver(drvName = "PostgreSQL")
db <-dbConnect(pgdrv,
                     dbname="DBMTCARS",
                     host="127.0.0.1", port=5432,
                     user = 'postgres')
copy_to(db, mtcars)
mtcars2 <- tbl(db, mtcars)

任务很简单,为每个组获取一个唯一的编号。
所以:

mtcars %>% mutate( gi = group_indices(., gear, carb))

现在我需要相同的数据库版本

mtcars2 %>% mutate( gi = group_indices(., gear, carb))

但是我得到了:

Error in UseMethod("escape") : no applicable method for 'escape' applied to an object of class "c('tbl_PostgreSQLConnection', 'tbl_dbi', 'tbl_sql', 'tbl_lazy', 'tbl')"

我知道如何使用 SQL 语法:

select *, (dense_rank over(order by gear, carb)) as gi FROM mtcars ;

但我想用 dplyr 语法或.. 如何在 tbl_dbi class 中直接使用 dbSendQuery?

提前致谢

正如@akrun 评论的那样,并非所有函数都会翻译。但是,在某些情况下,这可能对您有利。

这里有一个在 tidy verse 中使用 dense_rank 函数的方法:

approach1 = mtcars2 %>%
  mutate(combined_index = paste0(gear, carb)) %>%
  mutate(gi = dense_rank(combined_index))

我很确定 paste0dense_rank 都会通过 dbplyr 转换为 PostgreSQL,但无法在我当前的环境中进行测试。

或者,您可以利用以下事实:当 dbplyr 无法翻译命令时,它会保持原样。这意味着您可以将一些 PostgreSQL 命令直接写到您的 R 中。下面是一个使用这个想法的方法:

approach2 = mtcars2 %>%
  mutate(
             gi = sql("DENSE_RANK() OVER(ORDER BY gear, carb)")
        )

这个想法是因为 dbplyr 没有 DENSE_RANK 的翻译,所以它将按原样传递给 SQL 命令。这种方法的缺点是您无法轻松地将代码转移到没有 PostgreSQL.

的环境中

在执行其中任何一个之前,您可以通过检查它们是否产生正确的 SQL 语法来测试它们是否有效,如下所示:

approach1 %>% show_query()
approach2 %>% show_query()