У меня есть запрос dplyr в R, который фильтрует с помощью str_detect только для получения тех случаев, которые начинаются с букв «KS», но возвращает пустой тиббл. Я подключился к базе данных Oracle с помощью ROracle.

table <- tbl(con, "TABLE")

table %>% 
  filter(str_detect(COLUMN, "^KS"))

Однако, если я использую collect () для создания тибла, он работает:

table <- collect(tbl(con, "TABLE"))

table %>% 
  filter(str_detect(COLUMN, "^KS"))

Это почему? И как я могу заставить его работать без коллекторов? Некоторые из таблиц, которые мне нужны, слишком велики, чтобы их собирать.

Обновить: Если я изменю его для фильтрации по определенному значению столбца, например: table %>% filter(str_detect(COLUMN, "^KS")), оно работает. По какой-то причине регулярное выражение не работает без collect ().

0
Thomas Tallaksen 4 Окт 2018 в 14:21

2 ответа

Лучший ответ

Ричард Телфорд указал мне в правильном направлении ссылкой в комментариях. Это работает, если я вместо этого использую:

table <- tbl(con, "TABLE")

table %>% 
  filter(COLUMN %like% "%KS%")
0
Thomas Tallaksen 4 Окт 2018 в 12:23

Это могла быть проблема с переводом str_detect в запрос к базе данных:

b <- tbl(con,"pays")
filter(b,str_detect(nom,"^D")) %>% explain
#<SQL>
#SELECT *
#FROM "pays"
#WHERE (STRPOS("nom", '^D') > 0)


#<PLAN>
#Seq Scan on pays  (cost=0.00..5.31 rows=74 width=13)
#  Filter: (strpos(nom, '^D'::text) > 0)

b %>% filter(str_detect(nom, "^D")) %>% count
## Source:   lazy query [?? x 1]
## Database: postgres 9.6.1 [h2izgk@localhost:5432/postgres]
#      n
#  <dbl>
#1     0

К сожалению, STRPOS (я использовал PostgreSQL) не распознает значение '^', и запрос не выполняется. Так что вам следует использовать другую функцию, я обнаружил, что `grepl в порядке:

filter(b,grepl("^D",nom)) %>% explain
#<SQL>
#SELECT *
#FROM "pays"
#WHERE (("nom") ~ ('^D'))


#<PLAN>
#Seq Scan on pays  (cost=0.00..4.76 rows=54 width=13)
#  Filter: (nom ~ '^D'::text)

b %>% filter(grepl("^D", nom))
## Source:   lazy query [?? x 3]
## Database: postgres 9.6.1 [h2izgk@localhost:5432/postgres]
#  nom      pays  code 
#  <chr>    <chr> <chr>
#1 DANEMARK 101   208  
#2 DOUALA   ""    120  
#3 DAKAR    ""    686  
#4 DJIBOUTI 399   262

И результат правильный. В вашем примере collect решает проблему, поскольку сначала загружает всю таблицу в память R, а затем применяет str_detect без преобразования в SQL. Но это неэффективно.


0
Nicolas2 4 Окт 2018 в 12:07