在 dbplyr SQL 查询中的 string::str_detect 中使用带有正则表达式的变量
Use variable with regex in string::str_detect in dbplyr SQL query
我想根据正则表达式是否出现在任何列中来过滤 SQL 数据库。我想将正则表达式指定为变量;但是它被读取为文字字符串。我无法将正则表达式作为变量输入。感谢您的帮助!
我查阅过的资源:
注意:在 https://www.tidyverse.org/blog/2018/01/dbplyr-1-2/ 之后,我使用 mtcars 数据集制作 reprex 时遇到了问题。我收到错误消息:“错误:str_detect() 在此 SQL 变体中不可用”。我无法使用我的实际 SQL 数据库共享 reprex。因此,下面是一个伪代表。
library(dplyr)
library(stringr)
# Variable with regex (either lower- or uppercase "m")
my_string <- "(?i)m"
# WITHOUT SQL DATABASE ----------------------------------------------------
# This runs
mtcars %>%
tibble::rownames_to_column() %>%
filter(str_length(rowname) > 5)
# This runs with STRING
mtcars %>%
tibble::rownames_to_column() %>%
filter(str_detect(rowname, "(?i)m"))
# This runs with VARIABLE
mtcars %>%
tibble::rownames_to_column() %>%
filter(str_detect(rowname, my_string))
# WITH SQL DATABASE -------------------------------------------------------
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
mtcars_db <- copy_to(con, tibble::rownames_to_column(mtcars), "mtcars")
# This runs
tbl(con, "mtcars") %>%
filter(str_length(rowname) > 5)
# This *should* run with STRING -- pretend it does ;)
tbl(con, "mtcars") %>%
filter(str_detect(rowname, "M"))
# This does NOT run with VARIABLE
tbl(con, "mtcars") %>%
filter(str_detect(rowname, my_string))
这可能在很大程度上取决于您使用的 SQL 的风格。 This 问题提到了 str_detect
的翻译,还提供了一个替代方案。
正在测试 SQL 服务器:
library(dbplyr)
library(dplyr)
library(stringr)
data(mtcars)
df_sim = tbl_lazy(mtcars, con = simulate_mssql())
my_string <- "(?i)m"
df_sim %>%
filter(str_detect(my_string, gear)) %>%
show_query()
# Error: str_detect() is not available in this SQL variant
df_sim %>%
filter(gear %like% my_string) %>%
show_query()
# <SQL>
# SELECT *
# FROM `df`
# WHERE (`gear` like '(?i)m')
所以看起来 str_detect
无法转换为 SQL 服务器。但是您可以使用 %like%
作为解决方法。
正在测试 MySQL:
library(dbplyr)
library(dplyr)
library(stringr)
data(mtcars)
df_sim = tbl_lazy(mtcars, con = simulate_mysql()) # changed to mysql
my_string <- "(?i)m"
df_sim %>%
filter(str_detect(my_string, gear)) %>%
show_query()
# <SQL>
# SELECT *
# FROM `df`
# WHERE ('(?i)m' REGEXP `gear`)
df_sim %>%
filter(gear %like% my_string) %>%
show_query()
# <SQL>
# SELECT *
# FROM `df`
# WHERE (`gear` like '(?i)m')
看来 str_detect
可以正确翻译为 MySQL。
在每种情况下 my_string
都被翻译成查询。
还有几件事要检查:
- 正在更新 dbplyr 的版本。旧版本没有新版本中的所有翻译。
- 尝试使用行名以外的列。 R 中的数据框可以有行名,但 SQL 中的表只能有列。
在一位同事的帮助下,我有一个解决方案,可以在 string::str_detect:
中使用正则表达式强制计算变量
tbl(con, "mtcars") %>%
filter(str_detect(rowname, {{my_string}}))
我想根据正则表达式是否出现在任何列中来过滤 SQL 数据库。我想将正则表达式指定为变量;但是它被读取为文字字符串。我无法将正则表达式作为变量输入。感谢您的帮助!
我查阅过的资源:
注意:在 https://www.tidyverse.org/blog/2018/01/dbplyr-1-2/ 之后,我使用 mtcars 数据集制作 reprex 时遇到了问题。我收到错误消息:“错误:str_detect() 在此 SQL 变体中不可用”。我无法使用我的实际 SQL 数据库共享 reprex。因此,下面是一个伪代表。
library(dplyr)
library(stringr)
# Variable with regex (either lower- or uppercase "m")
my_string <- "(?i)m"
# WITHOUT SQL DATABASE ----------------------------------------------------
# This runs
mtcars %>%
tibble::rownames_to_column() %>%
filter(str_length(rowname) > 5)
# This runs with STRING
mtcars %>%
tibble::rownames_to_column() %>%
filter(str_detect(rowname, "(?i)m"))
# This runs with VARIABLE
mtcars %>%
tibble::rownames_to_column() %>%
filter(str_detect(rowname, my_string))
# WITH SQL DATABASE -------------------------------------------------------
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
mtcars_db <- copy_to(con, tibble::rownames_to_column(mtcars), "mtcars")
# This runs
tbl(con, "mtcars") %>%
filter(str_length(rowname) > 5)
# This *should* run with STRING -- pretend it does ;)
tbl(con, "mtcars") %>%
filter(str_detect(rowname, "M"))
# This does NOT run with VARIABLE
tbl(con, "mtcars") %>%
filter(str_detect(rowname, my_string))
这可能在很大程度上取决于您使用的 SQL 的风格。 This 问题提到了 str_detect
的翻译,还提供了一个替代方案。
正在测试 SQL 服务器:
library(dbplyr)
library(dplyr)
library(stringr)
data(mtcars)
df_sim = tbl_lazy(mtcars, con = simulate_mssql())
my_string <- "(?i)m"
df_sim %>%
filter(str_detect(my_string, gear)) %>%
show_query()
# Error: str_detect() is not available in this SQL variant
df_sim %>%
filter(gear %like% my_string) %>%
show_query()
# <SQL>
# SELECT *
# FROM `df`
# WHERE (`gear` like '(?i)m')
所以看起来 str_detect
无法转换为 SQL 服务器。但是您可以使用 %like%
作为解决方法。
正在测试 MySQL:
library(dbplyr)
library(dplyr)
library(stringr)
data(mtcars)
df_sim = tbl_lazy(mtcars, con = simulate_mysql()) # changed to mysql
my_string <- "(?i)m"
df_sim %>%
filter(str_detect(my_string, gear)) %>%
show_query()
# <SQL>
# SELECT *
# FROM `df`
# WHERE ('(?i)m' REGEXP `gear`)
df_sim %>%
filter(gear %like% my_string) %>%
show_query()
# <SQL>
# SELECT *
# FROM `df`
# WHERE (`gear` like '(?i)m')
看来 str_detect
可以正确翻译为 MySQL。
在每种情况下 my_string
都被翻译成查询。
还有几件事要检查:
- 正在更新 dbplyr 的版本。旧版本没有新版本中的所有翻译。
- 尝试使用行名以外的列。 R 中的数据框可以有行名,但 SQL 中的表只能有列。
在一位同事的帮助下,我有一个解决方案,可以在 string::str_detect:
中使用正则表达式强制计算变量tbl(con, "mtcars") %>%
filter(str_detect(rowname, {{my_string}}))