2017-12-20 14 views
1

큰 데이터 프레임 하나를 검색하기 위해 반짝이는 앱을 만들었고 stringi를 사용하려고 생각했습니다. 그러나 앱을 실행할 때 빈 검색 패턴이 지원되지 않는다는 경고가 표시됩니다. 이 예제 앱을 사용하면 위의 경고를 무시할 수 있지만 (스팸은 계속 발생 함) 큰 데이터 프레임 앱을 사용하면 모든 것이 느려지고 앱을 중지 할 수있는 유일한 방법은 R 세션을 종료하는 것입니다.데이터 프레임 검색을 위해 반짝이는 stringi를 사용하면 경고가 발생합니다.

## 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) 

나는 다음과 같은 경고 홍수 얻을이 응용 프로그램을 실행하면 : stri_detect_fixed (STR = 국가, 패턴 = 입력 $의 searchall)에서

경고 을 : 빈 검색 패턴이

을 지원하지 않습니다

이 경고와 함께 제공되는 속도 저하를 우회하는 최선의 방법은 무엇입니까?

답변

1

이 경우 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] 

UPDATE 2017년 12월 20일 : 20 밀리 빠른 stringi_detect_fixed()에 비해 실행하고, 두 번째 경우에 lgrepl() 첫 번째 테스트의 경우, stringi_detect_fixed() 60 밀리 빠른 lgrepl() 100 반복에 대한 것을 보여 microbenchmarks을 실행하는 코드를 추가합니다 요청의

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 
+0

감사합니다. srtingi가 각각의 필드에서 bigi-sh 덩어리로 큰 데이터 프레임을 가지고 여기에서 발견 된 것을 고려할 때 srtingi가 바람직한 옵션이라고 생각했습니다. https://stackoverflow.com/q/24257850/3967488 – magasr

+1

@magasr 게시 한 URL 충돌하는 타이밍, 한 대답은 grep()이 stringi_detect_fixed()보다 빠르다는 것을 보여 주며 다른 하나는 그 반대를 나타냅니다. 실제 문제에 대한 마이크로 벤치 마크를 포함하도록 게시물을 업데이트하면 해결 방법을 코딩 할 때 grepl()을 사용하면 검색 속도가 빨라지지만 stringi_detect_fixed()를 사용하면 검색 속도가 빨라집니다. 즉, 각 호출의 100 회 반복에 대한 결과는 서로 60 밀리 초 내에 있거나 개별 호출 기준으로 거의 구별 할 수 없습니다. –

+1

편집 : "... 100 반복에 대한 결과는 서로 60 마이크로 초 내에 있습니다". –