In this workshop, we will work with the Shiny R package (Chang et al., 2020) to build a web-based interface (a.k.a. dashboard) with interactive filtering options and a regular expression search field to dynamically explore textual data. Before the workshop, ensure you have the latest version of R and R studio installed in your computer. This workshop is part of the R-Ladies Athens meetup.

1 Before the workshop

  1. Download and install R from (If you are a Windows user, first determine if you are running the 32 or the 64 bit version)
  2. Download and install RStudio from

Alternatively, you can create a free R Studio cloud account at which is a cloud-based version of the R Studio IDE.

2 Demonstration (What are Shiny apps)?

Here’s an example of a shiny app for corpus exploration.

In this situation, this app is running in a wed server that is capable of running R. The user interface is run in the web browser (in the user’s computer). That is the case for any website, there is a server side and an interface side.

3 Starting a Shiny app

In a R Studio project, go:

In this situation, we are running the app locally. So our computer (or RStudio cloud) is the server that runs R behind the scenes.

4 Shiny app components

Like mentioned, there are two main parts of any shiny app:

The skeleton of a shiny app is as follows:


ui <- fluidPage()

server <- function(input, output) {}

shinyApp(ui = ui, server = server)

Look at the code in your app.R file, where’s the user interface and where’s the server? How are the two connected?

5 Changing the app components

Let’s look at the user interface first. There are two main elements in the interface, with one element holding other elements:

Change the titlePanel and run the app to see your change

As mentioned, the sidebarPanel is usually the place where you add the user input widgets. Here’s a list of the standard Shiny widgets (you can read more about these on this Shiny tutorial):

input function creates
actionButton Action Button
checkboxGroupInput A group of check boxes
checkboxInput A single check box
dateInput A calendar to aid date selection
dateRangeInput A pair of calendars for selecting a date range
fileInput A file upload control wizard
helpText Help text that can be added to an input form
numericInput A field to enter numbers
radioButtons A set of radio buttons
selectInput A box with choices to select from
sliderInput A slider bar
submitButton A submit button
textInput A field to enter text

Let’s add a selectInput widget to sidebarPanel, for the user to choose what variable to display in the histogram.

            "Choose variable:",
            c("eruptions" = 1,
              "waiting" = 2))

On the server side, change this line with the fixed column:

x    <- faithful[, 2]

To a version that reads in the user input.

x    <- faithful[, as.numeric(input$var)]

On the mainPanel we only have a plotOutput to display reactive output. Here’s a list of other functions that turn R objects into output:

output function creates
dataTableOutput DataTable
htmlOutput raw HTML
imageOutput image
plotOutput plot
tableOutput table
textOutput text
uiOutput raw HTML
verbatimTextOutput text

In the next section, we will work with htmlOutput.

6 Creating a new Shiny app for corpus exploration

For this part of the workshop, we will be using a package that contains the complete text of Jane Austen’s novels.

Our user interface we will have the following structure:

Here’s our app setup:

# load libraries

# create list of books in the data
books <- austen_books() %>%

We will keep the titlePanel element (but change the title) and the same layout (sidebarLayout). Our sidebarPanel will contain a selectInput and textInput. And our mainPanel will be just a htmlOutput.

# Define UI for application that displays text in a Austen book
ui <- fluidPage(

    # Application title
    titlePanel("Jane Austen's Complete Novels"),

    # Sidebar with a select input and search field
                        "Choose a book:",

        # display 

On the server side, let’s start with rendering the output for the selected book and search term.

# Define server logic required to display text 
# filtered by book selected and search term
server <- function(input, output) {

    output$dispText <- renderUI({
        HTML(austen_books() %>% 
                 filter(grepl(input$search, text)) %>%
                 filter(book == input$book) %>%


We can add a little bit of formatting to the output.

# Define server logic required to display text by book selected
# and search term
server <- function(input, output) {

    output$dispText <- renderUI({
        search_regex = paste0("(", input$search, ")")
        HTML(austen_books() %>% 
                 filter(grepl(input$search, text, = TRUE)) %>%
                 filter(book == input$book) %>%
                 mutate(text = gsub(search_regex, "<strong>\\1</strong>", text)) %>%
                 mutate(text = paste(text, '<br>')) %>%


7 Deploying your app to the web

You can create a free account at to deploy up to 5 applications.

This server is maintained by RStudio. It’s easy to use and secure.

8 Other resources