Фильтр Dplyr с str_detect возвращает пустой тиббл - PullRequest
0 голосов
/ 04 октября 2018

У меня есть запрос 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 ().

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Это может быть проблема с переводом 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 голосов
/ 04 октября 2018

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

table <- tbl(con, "TABLE")

table %>% 
  filter(COLUMN %like% "%KS%")
...