r语言 - dbplyr、dplyr 和没有 SQL 等价物的函数 [例如 'slice()']


library(tidyverse)
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
copy_to(con, mtcars)
mtcars2 <- tbl(con, "mtcars")

我可以在上面创建这个模拟SQL数据库。我可以在这个"数据库"上执行标准的 dplyr 功能,这很酷:

mtcars2 %>% 
group_by(cyl) %>% 
summarise(mpg = mean(mpg, na.rm = TRUE)) %>% 
arrange(desc(mpg))
#> # Source:     lazy query [?? x 2]
#> # Database:   sqlite 3.29.0 [:memory:]
#> # Ordered by: desc(mpg)
#>     cyl   mpg
#>   <dbl> <dbl>
#> 1     4  26.7
#> 2     6  19.7
#> 3     8  15.1

看来我无法使用没有直接SQL等效项的dplyr函数(例如dplyr::slice()(。在slice()的情况下,我可以使用filter()row_number()的替代组合来获得与仅使用slice()相同的结果。但是,如果没有这么简单的解决方法,会发生什么?

mtcars2 %>% slice(1:5)
#>Error in UseMethod("slice_") : 
#>  no applicable method for 'slice_' applied to an object of class 
#>  "c('tbl_SQLiteConnection', 'tbl_dbi', 'tbl_sql', 'tbl_lazy', 'tbl')"

当 dplyr 函数没有直接的 SQL 等价物时,我可以强制将它们与 dbplyr 一起使用,还是使用具有 SQL 等效项的 dplyr 动词进行创意的唯一选择,或者只是直接编写 SQL(这不是的首选解决方案(?

我理解了这个问题:如何使slice()适用于SQL数据库?这与"强制使用它们"不同,但仍然可能适用于您的情况。

下面的示例演示如何实现适用于数据库的slice()的"穷人"变体。我们仍然需要做跑腿工作并使用在数据库上运行的动词来实现它,但是我们可以像数据帧一样使用它。

阅读有关 http://adv-r.had.co.nz/OO-essentials.html#s3 中 S3 课程的更多信息。

library(tidyverse)
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
copy_to(con, mtcars)
mtcars2 <- tbl(con, "mtcars")
# mtcars2 has a class attribute
class(mtcars2)
#> [1] "tbl_SQLiteConnection" "tbl_dbi"              "tbl_sql"             
#> [4] "tbl_lazy"             "tbl"
# slice() is an S3 method
slice
#> function(.data, ..., .preserve = FALSE) {
#>   UseMethod("slice")
#> }
#> <bytecode: 0x560a03460548>
#> <environment: namespace:dplyr>
# we can implement a "poor man's" variant of slice()
# for the particular class. (It doesn't work quite the same
# in all cases.)
#' @export
slice.tbl_sql <- function(.data, ...) {
rows <- c(...)
.data %>%
mutate(...row_id = row_number()) %>%
filter(...row_id %in% !!rows) %>%
select(-...row_id)
}
mtcars2 %>%
slice(1:5)
#> # Source:   lazy query [?? x 11]
#> # Database: sqlite 3.29.0 [:memory:]
#>     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1  21       6   160   110  3.9   2.62  16.5     0     1     4     4
#> 2  21       6   160   110  3.9   2.88  17.0     0     1     4     4
#> 3  22.8     4   108    93  3.85  2.32  18.6     1     1     4     1
#> 4  21.4     6   258   110  3.08  3.22  19.4     1     0     3     1
#> 5  18.7     8   360   175  3.15  3.44  17.0     0     0     3     2

创建于 2019-12-07 由 reprex 软件包 (v0.3.0(

相关内容

最新更新