aprendiz
aprendiz

Reputation: 611

How to create a keyword search in a Shiny App?

I'm trying to build a Shiny App so that users can 'interact' with a group of sentences that I have in a dataframe. The dataframe looks like this:

# id: each sentence has a unique number
# file: name of the file the sentence comes from
# sentence: the actual sentence
# group: group the writer belongs to
# gender: writer's gender

id    file    sentence               group    gender
1     101s    the tree is tall.        A       female
2     101s    the sun is yellow.       A       female
3     102s    he reads a book.         D       male 
4     102s    she goes shopping.       D       male
5     103s    they drive the car.      B       female
...

I want to create a 'keyword in context' search bar using R Shiny. Basically, users would type in a word, and the app would retrieve the sentences that contain that word.

This is the code I included in my ui.R file for that specific purpose:

sidebarPanel(
   textInput("Input_KWIC", "Enter a keyword:"),
mainPanel(htmlOutput("Text_KWIC")))),

And this is the code I included in my server.R file.

output$Text_KWIC = renderUI({
        data %>%
            filter(grepl(input$Input_KWIC, sentence)) %>%
            pull(sentence)
        })

When I run the app, I get this error: "Text to be written must be a length-one character vector" (this is after I type in my keyword).

I don't know what I'm doing wrong nor whether the error is in the UI or the server.

Upvotes: 0

Views: 908

Answers (1)

DPH
DPH

Reputation: 4344

You are getting the error message, because there is more then one possible result the way you have set up the server function. Bear in mind, that when the app starts the text box is empty and therefore the return of your function is a vector with more than one value (in fact all values) and renderUI does only digest "Shiny tag object, HTML, or a list of such objects".

Now you can search for values and will get responses though again sometimes the response vector has more than one value/item and this will lead to the same error.

So here is what you can do:

  • just select the first value of the search result:

      data %>%
          dplyr::filter(grepl(input$Input_KWIC, sentence)) %>%
          dplyr::pull(sentence) %>%
          .[1]
    
  • convert output to list

      df %>%
          dplyr::filter(stringr::str_detect(sentence, pattern = input$Input_KWIC)) %>%
          dplyr::pull(sentence) %>%
          as.list()
    
  • change the renderUI() and htmlOutput() to renderText() and textOuput(), which will get you all results strings listed one after another

  • probably will work but a bit more effort: build html output for multiple value inside the render function

  • follow @rawrs advice and use some sort of table output

Upvotes: 1

Related Questions