当前位置: 首页 > 面试题库 >

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

冷浩瀚
2023-03-14
问题内容

我正在使用dplyr的自动SQL后端从数据库表查询子表。例如

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列出一个列表,但不适用于更一般的正则表达式)


问题答案:

一个“ dplyr-only”解决方案是这样

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

完整说明:

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为他最近的评论 点击这里



 类似资料:
  • 问题内容: 请告知如何将参数传递给使用的函数。 我的例子是不正确的。 问题答案: 您需要创建一个匿名函数,以便不会立即执行实际函数。

  • 我需要通过函数从到(在按钮内)。但是我想我只能在中定义变量,但不能定义为函数。你能解释一下我该如何称呼和定义它吗?

  • 问题内容: 我有一个简单的跨度 此范围在表内,每行都有一个删除范围。 然后,当单击该跨度时,我使用AJAX调用URL。AJAX事件需要知道该行的对象ID吗?使该ID进入点击功能的最佳方法是什么? 我以为我可以做这样的事情 但是ID不能以数字开头吗?对?那我以为我可以 然后从ID中删除“我的”部分,但这似乎很Yu! 以下是我的点击事件以及我的AJAX事件所在的位置。 我确定有一个不错的方法吗? 注意

  • 我当时正在读一本名为《现代Java在行动》的书,其中一部分代码我无法理解。 作者表示,代码不会终止。原因是无法在过滤器中知道数字是否继续增加,因此它会无限地继续过滤它们! 我不明白原因。有人能解释一下为什么吗。

  • 问题内容: 这是我的config.json: 这是我的bash命令: 输出: 因此$ PRJNAME是prj1,但是第一次调用仅输出。 有人能帮我吗? 问题答案: 您的示例中的jq程序实际上会尝试查找名为的键。请尝试以下操作:

  • 问题内容: 是否可以将参数传递给filter函数,以便您可以按任何名称进行过滤? 就像是 问题答案: 实际上,还有另一种(也许是更好的解决方案),您可以使用angular的本机“过滤器”过滤器,并且仍将参数传递给自定义过滤器。 考虑以下代码: 要进行此工作,您只需将过滤器定义如下: 如您在这里看到的,weDontLike实际上返回另一个函数,该函数的范围内有您的参数以及来自过滤器的原始项。 我花了