Highlight word in DT in shiny based on regex

Instead of relying on datatable's search functionality you can create a reactive element that first filters by the input, and then replaces the matching words with the same word embedded in a <span style="background-color:yellow;"> tag. This should allow more search flexibility via more complex regex.

You'll need to add escape = F to datatable so the HTML tag is interpreted properly. I've added options = list(dom = "lt") to datatable to remove the datatable's search field and direct attention to the left search field.

The filtering criteria are left fairly fuzzy to keep the table from disappearing until a perfect match is found – i.e. the table shouldn't disappear when you type "o" because there's no perfect match, and then reappear at "on". The highlights then only appear if a matching word is found, i.e. on, On, and on., but not stone, scone, etc. Here's a glimpse of what it looks like:

enter image description here

And here's the code. Note that I use dplyr's filtering and mutating functions because they can easily be applied to multiple columns via their *_all variants:

library(shiny)
library(DT)
library(data.table)
library(dplyr) # For `filter_all` and `mutate_all`.

example_data <- iris
    # data.table(words = c("on", "scone", "wrong", "stone"), 
    #                        description = c("The word on", "Scone is not on.", "Not on either", "Not here at all"))

ui = shinyUI(fluidPage(

    sidebarLayout(
        sidebarPanel(
            textInput("word_select", label = "Word to search")
        ),
        mainPanel(
            dataTableOutput("word_searched")
        )
    )
))

server = shinyServer(function(input, output, session) {

    # This is your reactive element.
    df_reactive <- reactive({
            example_data %>%
                # Filter if input is anywhere, even in other words.
                filter_all(any_vars(grepl(input$word_select, ., T, T))) %>% 
                # Replace complete words with same in HTML.
                mutate_all(~ gsub(
                              paste(c("\\b(", input$word_select, ")\\b"), collapse = ""),
                              "<span style='background-color:yellow;'>\\1</span>",
                              .,
                              TRUE,
                              TRUE
                              )
                          )
    })

    # Render your reactive element here.
    output$word_searched <- renderDataTable({
        datatable(df_reactive(), escape = F, options = list(dom = "lt"))
    })

})

shinyApp(ui = ui, server = server)

Tags:

R

Dt

Shiny