Blog

rshiny

In previous blog posts, I discussed the use of software such as AntConc or Voyant to analyze corpus data. Even though these are very helpful, you can only use them to perform the range of default analyses they offer. But, what if you need more customization? Maybe you want to create your own graphs or explore your data in ways that go beyond traditional KWIC analyses and basic word frequencies. Well, then keep reading because that is totally possible!

In this blog post, I introduce R Shiny, which allows you to create a web-based interface (aka. a dashboard) to explore your textual data in any way you want.

How to start using R Shiny

To use R Shiny, you first need to download and install R, which you can find here. I also recommend installing R Studio, the most popular IDE for R.

Once you have R and R Studio installed, you can proceed to install R Shiny. In this case, R Shiny is an R package that you can install using the following command:

install.packages("shiny")

 

Don't forget you also need to load the package after installing it (you will have to do this every time you open R Studio):

library(shiny)

 

Now, you're ready to create a Shiny app!

Click on File > New File > Shiny Web App, and then in the window, give it a name and choose a directory.

rshiny-setup

Once you have done this, you will see that the new file already comes with some code in it. Specifically, this is what you should see:

  • The default name of your new file is app.R

  • Your code includes a function called ui, and

  • a function called server

  • At the end of your file, there is this command: shinyApp(ui = ui, server = server)

All R Shiny apps have two parts: a UI (user interface) and a server. The UI is what you see: graphs, fonts, colors, images, and so on. The server is what the app does but which you don't see: in this case, the functions and commands to analyze your data.

This means that you will have to tell R what to do with your data, as well as how to display it in the app. I will cover these two things later on. But first, let's import some data!

For this tutorial, I will use a corpus (R package sherlock) that contains the full texts of Sherlock Holmes stories, though you can use any textual data you want. To provide you with some context, this package comes with the holmes dataset, which has two columns: one that contains lines of text from the stories (text) and another one that contains the title of the story each line is taken from (book).

# Sample rows from the dataset
    text                      book
29  CHAPTER I                 A Study In Scarlet
30  Mr. Sherlock Holmes       A Study In Scarlet
31  In the year 1878 I took my degree of Doctor of Medicine of the                        A Study In Scarlet
32  University of London, and proceeded to Netley to go through the                   A Study In Scarlet
33  course prescribed for surgeons in the army. Having completed my                  A Study In Scarlet
34  studies there, I was duly attached to the Fifth Northumberland                A Study In Scarlet

 

In addition to loading the sherlock package, I will also load the tidyverse package, which is very helpful to work with data.

How to add components to the UI of your Shiny app

Before diving into the analyses, I think it's important to look at the UI first to better understand what it does. The ui function contains some elements that you can either keep or modify.

The first element is titlePanel, which is the title of your R Shiny app. If you think of your app as a website, the title would be the name of your website and it would be displayed at the top of the page by default. I will change the current title (Old Faithful Geyser Data) to Textual analysis of Sherlock Holmes, which describes what my app is about.

You can take a look at what the app looks like now by clicking on the Run App button located on the upper menu. A new window will open up where you can see the app:

rshiny-title

You can see that the R Shiny app now displays the new title. You will also see a graph (a histogram, in this case) accompanied by a slider that allows you to enter a value. This is based on random data provided to the R Shiny app via the server function, which we will modify later.

Basically, the goal is to display data from the Sherlock Holmes stories together with some components that will allow the user to filter and/or select different values or types of analyses.

Ok, so what other components are there? Actually, there are tons of them, and they're usually referred to as "widgets" or "Shiny widgets". You will usually specify widgets within the sidebarPanel section of your code. The idea here is to replace sliderInput with any other widget (or widgets) you want. These are some of the most popular ones:

Widget What it does
radioButtons a set of radio buttons
checkboxGroupInput a group of check boxes
selectInput a box with choices to select from
textInput a field to enter text
numericInput a field to enter numbers

 

To learn about all Shiny widgets and see real examples, visit this link.

How to do a basic textual data analysis using R Shiny

For this tutorial, I will add a couple of Shiny widgets that will allow users to select one of the Sherlock Holmes stories and then run a simple KWIC search.

Once you master these basic things, you'll be ready to take your app further by adding visualizations, as well as other types of analyses, since the process is very similar.

Filtering textual data

If you remember, the holmes dataset contains a column called books with the titles of all the stories. I will add a selectInput widget so that the data can be filtered out to display only text from a given book.

First, I will create an R vector which contains the title of each story:

books = unique(holmes$book)

 

Now, I will add the selectInput widget to the `ui` function:

    sidebarLayout(
        sidebarPanel(
            selectInput("book", # input ID (aka. a unique name for this widget)
                        "Choose a story: ", # label (aka. what the app displays)
                        books) # choices (aka. the vector)
        ),

 

If you click on the Run app button again, you will now see a drop-down menu in your app which lists all Sherlock Holmes stories.

rshiny-select

This looks great, though when you select a title, nothing happens! That's because you first need to create an "output function". That is, you need to tell R that when you select a book from this drop-down menu, you want to see the text from that book in the UI.

To do that, you need to modify the second part of the ui function (called mainPanel) as well as the server function:

  • Just like with Shiny widgets to enter some input, we also have Shiny Outputs. For example, you can display a table, a graph, an image, or just text, like we want now. In mainPanel, I will include an HTML output (htmlOutput), which basically displays text using an HTML format. You can learn more about different Shiny outputs here.

        mainPanel(
           htmlOutput("displayedText" # output ID (aka. a unique name for this output)
                      )
        )

 

  • In the server function, we need to do the filtering based on the title chosen. See how I used input$book (the input ID) as a placeholder for the title chosen as well as output$displayedText (the output ID).

server <- function(input, output) {

    output$displayedText = renderUI({
        # filter text based on the title selected
        HTML(holmes %>%
               filter(book == input$book) %>%
               pull(text))
    })
}

 

Ok, so now, when you run the app and you choose a story from the drop-down menu, you should finally see the text on the right.

rshiny-output

Running a KWIC search

Now, we will add a second Shiny widget to search for a specific keyword. That is, users will select a book from the drop-down menu and then they will type a keyword they want to find, so that only sentences containing that keyword will show up on the right.

The widget we need for this is textInput, and we will add it after our previous selectInput widget. Don't forget to add an input ID and a label:

    sidebarLayout(
        sidebarPanel(
            selectInput("book",
                        "Choose a story: ",
                        books),
            textInput("input_KWIC", # input ID (aka. a unique name for this widget)
                      "Find a keyword: ") # label (aka. what the app displays)
        ),

 

Once this is done, we also need to edit the server function so that it filters text based on the keyword chosen.

Here, we will simply edit output$displayedText to add a second filter function. I also recommend using a mutate function to edit the output a little bit. In this case, I added a an HTML break (br/) after each line of text so that the output is clearer.

output$displayedText = renderUI({
        # filter text based on the title selected and KWIC
        HTML(holmes %>%
               filter(book == input$book) %>%
               filter(grepl(input$input_KWIC, text, ignore.case = TRUE)) %>%
               mutate(text = paste(text, '<br/>')) %>%
               pull(text))
    })

 

If you now run the app, you will be able to try this second widget. For example, I selected the story titled A Case of Identity and searched for the keyword "Holmes". On the right, I can see all sentences containing that keyword (one sentence per line).

rshiny-kwic

Customizing the UI

Ok, so now the app is working, but it looks boring! Fortunately, we can customize the UI to make the app prettier.

The easiest option is to install the R package shinythemes and then use one of the available Shiny themes (you can take a look at them first here. You will have to add the name of the theme at the beginning of your UI function:

# I chose the "cerulean" theme
ui <- fluidPage(theme = shinytheme("cerulean"),

 

This is what the app looks like with that theme:

rshiny-theme

If you want to customize your app further, you can add CSS code to your app, as you would normally do with any other website. To get started, visit this link.

How to publish your Shiny app

So far, I have described how to get started with R Shiny. But, what if you create a great app and you want other people to be able to see it and play around with it? In order to do that, you need to deploy your app.

You can host your app for free on shinyapps.io by creating an account. However, if you want to deploy more than 5 Shiny apps, you will have to switch to a paid plan. Alternatively, you can also host your Shiny app on a different platform, such as AWS.

 

 

If you found this post interesting, you can check out my other blog posts here!