Каков подход tidyeval в использовании dplyr :: filter с базой данных, когда условие указано в виде строки? - PullRequest
0 голосов
/ 26 марта 2020

Я не могу понять, как использовать dplyr::filter с базой данных, когда условие указано в виде строки. dplyr::filter_ здесь просто, но не рекомендуется.

suppressPackageStartupMessages(library(dplyr))
con <- DBI::dbConnect(RSQLite::SQLite(), dbname = ":memory:")
copy_to(con, iris, "iris", temporary = FALSE)
iris_db <- tbl(con, "iris")
filter_str <- "Species == 'setosa'"

Сначала попробуйте выполнить фильтрацию на фрейме данных

iris_db %>% collect() %>% filter(eval(parse(text = filter_str))) %>% count()
#> # A tibble: 1 x 1
#>       n
#>   <int>
#> 1    50

Теперь попробуйте выполнить это в базе данных, используя filter_

iris_db %>% filter_(filter_str) %>% collect() %>% count()
#> Warning: filter_() is deprecated. 
#> Please use filter() instead
#> 
#> The 'programming' vignette or the tidyeval book can help you
#> to program with filter() : https://tidyeval.tidyverse.org
#> This warning is displayed once per session.
#> # A tibble: 1 x 1
#>       n
#>   <int>
#> 1    50

Теперь попробуйте это в базе данных, используя filter. Это терпит неудачу.

iris_db %>% filter(eval(parse(text = filter_str))) %>% collect() %>% count()
#> Warning: Named arguments ignored for SQL parse
#> Error: near "AS": syntax error

И именно поэтому оно терпит неудачу

iris_db %>% filter(eval(parse(text = filter_str))) %>% show_query() 
#> <SQL>
#> Warning: Named arguments ignored for SQL parse
#> SELECT *
#> FROM `iris`
#> WHERE (eval(parse('Species == ''setosa''' AS `text`)))

Создано в 2020-03-26 пакетом prex (v0. 3,0)

1 Ответ

0 голосов
/ 26 марта 2020

Используйте rlang::parse_expr.

library(dplyr)

iris_db %>% filter(!!rlang::parse_expr(filter_str)) %>% collect() %>% count()

#      n
#  <int>
#1    50

Возвращает запрос:

iris_db %>% filter(!!rlang::parse_expr(filter_str)) %>% show_query()

#<SQL>
#SELECT *
#FROM `iris`
#WHERE (`Species` = 'setosa')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...