将 stringi 与 shiny 一起用于搜索数据框会产生警告

Using stringi with shiny for searching the dataframe produces warnings

我做了一个闪亮的应用程序来搜索一个大数据框,我想到了使用 stringi。但是,当我 运行 该应用程序时,我收到一条警告,指出不支持空搜索模式。使用此示例应用程序,我可以很好地忽略此警告(尽管它一直在发送垃圾邮件),但是使用我的大数据框应用程序会减慢一切,我可以停止该应用程序的唯一方法是终止 R 会话。

## app.R ##
require(shiny)
require(stringi)
require(dplyr)
require(DT)

ui <- fluidPage(textInput("searchall", label =  "Search"),
            dataTableOutput("tableSearch"))

server <- function(input, output, session) {
  data(GNI2014)
  output$tableSearch <- DT::renderDataTable(datatable(
  GNI2014 %>% filter(
      if (!is.null(input$searchall))
        stri_detect_fixed(str = country , pattern = input$searchall)
    ),
    options = list(sDom  = '<"top">lrt<"bottom">ip')
  ))
}

shinyApp(ui, server)

当我 运行 这个应用程序时,我收到以下警告:

Warning in stri_detect_fixed(str = country, pattern = input$searchall) : empty search patterns are not supported

绕过此警告和随之而来的减速的最佳方法是什么。

您不需要 stringi()。查询数据最快的方法是使用 data.table()country 上的键,并使用 grepl() 对数据进行子集化。

使用 treemap 包中的 GNI2014 数据的示例。

library(treemap)
library(data.table)
data(GNI2014)
gni2014table <- data.table(GNI2014)
setkey(gni2014table,"country")
searchText <- "berm"
gni2014table[grepl(searchText,gni2014table$country,ignore.case=TRUE),]

searchText <- "United"
gni2014table[grepl(searchText,gni2014table$country,ignore.case=TRUE),]

...和输出。

> library(treemap)
> library(data.table)
> data(GNI2014)
> gni2014table <- data.table(GNI2014)
> setkey(gni2014table,"country")
> searchText <- "berm"
> gni2014table[grepl(searchText,gni2014table$country,ignore.case=TRUE),]
   iso3 country     continent population    GNI
1:  BMU Bermuda North America      67837 106140
> 
> searchText <- "United"
> gni2014table[grepl(searchText,gni2014table$country,ignore.case=TRUE),]
   iso3              country     continent population   GNI
1:  ARE United Arab Emirates          Asia    4798491 44600
2:  GBR       United Kingdom        Europe   62262000 43430
3:  USA        United States North America  313973000 55200
>

仅返回要填充 UI 字段的列,如下所示。

searchText <- "United Arab"
gni2014table[grepl(searchText,gni2014table$country,ignore.case=TRUE),country]

更新 2017 年 12 月 20 日:将代码添加到 运行 微基准测试,表明在第一个测试用例中 lgrepl() 运行s 快 20 毫秒比 stringi_detect_fixed(),在第二种情况下,对于请求的 100 次迭代,stringi_detect_fixed()lgrepl() 快 60 毫秒。

library(treemap)
library(data.table)
library(microbenchmark)
data(GNI2014)
gni2014table <- data.table(GNI2014)
setkey(gni2014table,"country")
searchText <- "berm"

microbenchmark(gni2014table[grepl(searchText,gni2014table$country,
                                  ignore.case=TRUE),])

searchText <- "United Arab"
microbenchmark(gni2014table[grepl(searchText,gni2014table$country,
                                  ignore.case=TRUE),country])

library(stringi)
searchText <- "berm"

microbenchmark(gni2014table[stri_detect_fixed(searchText,
                              gni2014table$country,
                              case_insensitive=TRUE),])

searchText <- "United Arab"

microbenchmark(gni2014table[stri_detect_fixed(searchText,
                            gni2014table$country,case_insensitive=TRUE),])

您必须自己 运行 代码才能重现基准测试,因为 microbenchmark() 的输出在 SO 上不容易显示。

也就是说,时间的总结版本是:

searchText      Function             Mean (in Microseconds)
-------------   -------------------- -----------------------
berm            grepl                526.2545
United Arab     grepl                583.1789
berm            stringi_detect_fixed 545.8772
United Arab     stringi_detect_fixed 524.1132