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.
Alternatively, you can create a free R Studio cloud account at https://rstudio.cloud/ which is a cloud-based version of the R Studio IDE.
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.
In a R Studio project, go:
Run App
button on the top of the scriptRun in Window
Run App
In this situation, we are running the app locally. So our computer (or RStudio cloud) is the server that runs R behind the scenes.
Like mentioned, there are two main parts of any shiny app:
The skeleton of a shiny app is as follows:
library(shiny)
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 theserver
? How are the two connected?
Let’s look at the user interface first. There are two main elements in the interface, with one element holding other elements:
titlePanel
sidebarLayout
sidebarPanel
that contains only a sliderInput
mainPanel
that contains a plotOutput
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.
selectInput("var",
"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
.
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:
titlePanel
sidebarLayout
sidebarPanel
selectInput
with a list of book titletextInput
for corpus searchesmainPanel
that contains a htmlOutput
to display formatted textHere’s our app setup:
# load libraries
library(janeaustenr)
library(shiny)
library(tidyverse)
# create list of books in the data
books <- austen_books() %>%
distinct(book)
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
sidebarLayout(
sidebarPanel(
selectInput("book",
"Choose a book:",
books),
textInput("text_to_display",
"Search:")
),
# display
mainPanel(
htmlOutput("dispText")
)
)
)
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) %>%
pull(text))
})
}
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, ignore.case = TRUE)) %>%
filter(book == input$book) %>%
mutate(text = gsub(search_regex, "<strong>\\1</strong>", text)) %>%
mutate(text = paste(text, '<br>')) %>%
pull(text))
})
}
You can create a free account at shinyapps.io to deploy up to 5 applications.
This server is maintained by RStudio. It’s easy to use and secure.