Wordcloud Web App In 40 Lines of R

Kade Killary · 2017.10.18 · 6 minutes until it's over

wordcloudr

R is having quite the growth spurt these days. This popularity may seem peculiar given its statistical roots. However, through the amazing work of Hadley Wickham, and the entire R Studio team, this is changing. One example of this newfound power is being able to write crisp web apps in a laughably minuscule amount of code. In this piece, I’ll walk through how to create a simple wordcloud web app above using just R! No Javascript, HTML or CSS whatsoever.

  finalproject  

Up & Running

  helloworld  

The pathway to Hello World is straightforward. You’ll need to install R. For Mac users the simplest way is Homebrew. If not, you can always get it from CRAN. You get an R console by simply typing R at your terminal of choice.

Next, you’ll want to create a file called app.R with the code below. The main driver behind everything we will be doing is an R package called Shiny. What exactly is this magical package?

Shiny is an open source R package that provides an elegant and powerful web framework for building web applications using R. Shiny helps you turn your analyses into interactive web applications without requiring HTML, CSS, or JavaScript knowledge.

# contents of app.R

library(shiny)

ui <- fluidPage(

  titlePanel('Hello World')
  
)

server <- function(input, output) {

}

shinyApp(ui, server)

Once you’ve done that. You can run the app by invoking R and typing:

library(shiny)
shiny::runApp()

  Pretty easy right? Welp, that’s only the beginning.  

At this point, we’ve got our project off the ground. The next step is to add in the sidebar, sliders and set up our main panel.

# contents of app.R

library(shiny)

ui <- fluidPage(
  
  # our title
  titlePanel('Wordcloud Web App'),
  
  # defining the sidebar
  sidebarLayout(
  
    # setting up our sidebar
    sidebarPanel(
   
      # our first slider
      sliderInput('ngramCount', '# of Grams', min = 1, max = 5, value = 2),
    
      hr(),
      # second slider
      sliderInput('cloudCount', '# of Words', min = 50, max = 400, value = 100),
   
    # setting up main panel
    mainPanel(
    
      # defining where our cloud will appear
      plotOutput('wordcloud')
    )
  )
)

server <- function(input, output) {

}

shinyApp(ui, server)

Even though some of the syntax is new it’s fairly straightforward. We defined our page style with fluidPage, which allows for us to tap into Bootstrap’s grid system. Then, we set up our sidebar. Next we set up two sliderInputs. This will allow for the user to change values in our wordcloud, which will be reflected instantly in our cloud. This focus on inputs and the subsequent changes from them lies at the heart of Shiny. The methodology underlying this process is reactivity.

For the most part, reactivity falls outside of the scope of this article, but I’ll provide a quick overview from the good folks over at RStudio.

The Shiny web framework is fundamentally about making it easy to wire up input values from a web page, making them easily available to you in R, and have the results of your R code be written as output values back out to the web page.

input values => R code => output values

Since Shiny web apps are interactive, the input values can change at any time, and the output values need to be updated immediately to reflect those changes.

Shiny comes with a reactive programming library that you will use to structure your application logic. By using this library, changing input values will naturally cause the right parts of your R code to be reexecuted, which will in turn cause any changed outputs to be updated.

We’ve completed all the code we’ll need for the UI for this app. Now, we’ll focus on the server side. The following syntax will look absolutely alien if you’re new to R and the Tidyverse, but bear with me. It’s easier than it appears.

server <- function(input, output) {

  # defining a reactive function
  # reacts to changes in the ngram slider
  # by taking it out of the output$wordcloud function
  # we have more control over when our dplyr statement
  # will get updated
  ngrams <- reactive({
  
    # the $<name> is used to reference the name
    # we gave our ngram sliderInput earlier
    input$ngramCount
  
  })
  
  # the $<name> here is referencing the name
  # we defined in the plotOutput('wordcloud')
  # earlier in the mainPanel
  output$wordcloud <- renderPlot({
  
    # our text is coming from the janeaustenr package
    austen_books() %>%
    
      # the %>% is a pipe operator
      # will take left side and pass it through
      # same as linux piping
      
      # selecting our column
      select(text) %>%
      
      # turning text into an ngram with count selected by user
      unnest_tokens(ngram, text, token="ngrams", n=ngrams()) %>%
      
      # getting occurence count of each ngram
      count(ngram)
      
      # setting up our wordcloud to use ngrams, sorted by count (n)
      # user can adjust max.words shown with slider
      with(wordcloud(ngram, n, max.words=input$cloudCount, rot.per=.2,
        colors=c("#b4b3b3", "#969696", "#484848", "#8dc7d3")
  
  })
}

And believe it or not, that’s it. You’ll need to declare what libraries you’re using if you try to run this locally. You can find the final code for this walkthrough here.

This walkthrough was by no means exhaustive. Shiny has a lot to offer, with a seemingly endless toolbox. You can write custom HTML and CSS if you want. Plus, packages like ShinyJS will give more experienced devs a chance to really let their apps shine by tapping into Javascript.

Hopefully, this brief overview reveals how easy + fun working with R and Shiny is. It can be really great for internal tooling around models or data viz. Definitely worth a weekend hack session. You can see a gallery of examples on RStudio to get some inspiration.

 


 

If you’re looking for a more in-depth tutorial this one by Dean Attali is a great place to start!