具有 str_detect returns 空标题的 Dplyr 过滤器
Dplyr filter with str_detect returns empty tibble
我在 R 中有一个 dplyr 查询,它使用 str_detect 进行过滤以仅获取以字母 "KS" 开头的案例,但它 returns 是一个空的小标题。我使用 ROracle 连接到 Oracle 数据库。
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(),正则表达式将无法工作。
Richard Telford 在评论中用 link 为我指明了正确的方向。如果我改为使用它,它会起作用:
table <- tbl(con, "TABLE")
table %>%
filter(COLUMN %like% "%KS%")
可能是将 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
解决了问题,因为它首先将整个 table 下载到 R 内存中,然后应用 str_detect
而没有转换为 SQL。但是效率不高。
我在 R 中有一个 dplyr 查询,它使用 str_detect 进行过滤以仅获取以字母 "KS" 开头的案例,但它 returns 是一个空的小标题。我使用 ROracle 连接到 Oracle 数据库。
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(),正则表达式将无法工作。
Richard Telford 在评论中用 link 为我指明了正确的方向。如果我改为使用它,它会起作用:
table <- tbl(con, "TABLE")
table %>%
filter(COLUMN %like% "%KS%")
可能是将 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
解决了问题,因为它首先将整个 table 下载到 R 内存中,然后应用 str_detect
而没有转换为 SQL。但是效率不高。