在数据库的dplyr过滤器函数中传递SQL函数

时间:2016-08-15 20:31:12

标签: sql r postgresql dplyr

我正在使用dplyr的自动SQL后端来查询数据库表中的子表。 E.g。

my_tbl <- tbl(my_db, "my_table")

数据库中的my_table看起来像

batch_name    value
batch_A_1     1
batch_A_2     2
batch_A_2     3
batch_B_1     8
batch_B_2     9
...

我只想要来自batch_A_#的数据,无论数字是多少。

如果我在SQL中写这个,我可以使用

select * where batch_name like 'batch_A_%'

如果我在R中写这个,我可以使用几种方法来实现这一点:grepl()%in%str_detect()

# option 1
subtable <- my_tbl %>% select(batch_name, value) %>%
    filter(grepl('batch_A_', batch_name, fixed = T))
# option 2
subtable <- my_tbl %>% select(batch_name, value) %>%
    filter(str_detect(batch_name, 'batch_A_'))

所有这些都会产生以下Postgres错误:HINT: No function matches the given name and argument types. You might need to add explicit type casts

那么,如何传递SQL字符串函数或匹配函数以帮助使生成的dplyr SQL查询能够在filter中使用更灵活的函数范围?

(仅供参考%in%函数确实有效,但需要列出所有可能的值。这可以与paste结合使用来制作列表,但不适用于更一般的正则表达式案例)

1 个答案:

答案 0 :(得分:5)


dplyr - 仅”解决方案就是这个

tbl(my_con, "my_table") %>% 
  filter(batch_name %like% "batch_A_%") %>% 
  collect()

完整reprex

suppressPackageStartupMessages({
  library(dplyr)
  library(dbplyr)
  library(RPostgreSQL)
})

my_con <- 
  dbConnect(
    PostgreSQL(),
    user     = "my_user",
    password = "my_password",
    host     = "my_host",
    dbname   = "my_db"
  )

my_table <- tribble(
  ~batch_name,    ~value,
  "batch_A_1",     1,
  "batch_A_2",     2,
  "batch_A_2",     3,
  "batch_B_1",     8,
  "batch_B_2",     9
)

copy_to(my_con, my_table)

tbl(my_con, "my_table") %>% 
  filter(batch_name %like% "batch_A_%") %>% 
  collect()
#> # A tibble: 3 x 2
#>   batch_name value
#> *      <chr> <dbl>
#> 1  batch_A_1     1
#> 2  batch_A_2     2
#> 3  batch_A_2     3

dbDisconnect(my_con)
#> [1] TRUE

这是有效的,因为dplyr不知道如何使用的任何函数 翻译将按原样传递,请参阅 ?dbplyr::translate\_sql

最近的评论给@PaulRougieux提示 here