R: Your first web application with shiny

R: Your first web application with shiny

Data driven journalism doesn’t necessarily involve user interaction. The analysis and its results may be enough to write a dashing article without ever mentioning a number. But let’s face it: We love to interact with data visualizations! To build those, some basic knowledge of JavaScript and HTML is usually required.
What? Your only coding skills are a bit of R? No problemo! What if I told you there was a way to interactively show users your most interesting R-results in a fancy web app?

Shiny to the rescue

Shiny is a highly customizable web application framework that turns your analysis into an interactive web app. No HTML, no JavaScript, no CSS required — although you can use it to expand your app. Also, the layout is responsive (although it’s not perfect for every phone).

In this tutorial, we will learn step by step how to code the shiny app on Germany’s air pollutants emissions that you can see below.

Note: As I chose this data merely as an example, I didn’t verify it or ensure to display it the correct way. The focus lies on demonstrating how to build a shiny app with a reactive plot, no matter which data is used. This is why you should not regard the plot output as best practice data journalism, although you can still use the dataset to practice with shiny. As you can read in the comments, it wouldn’t really make sense as an actual visualization to plot PM 2.5 and TSP in a stacked barchart.

As always, you’ll find the raw code of the app, the data and a markdown in our GitHub repository. Visit the shiny gallery to explore the other diverse examples of shiny apps out there!

The app has a header panel with a title and an image, a sidebar panel with two different types of input select options and a main panel split into three different tabs containing a barchart, the data table and also an R markdown document. You can choose multiple air pollutants as well as years and see how the graph and the data table change according to your input. The app is coded entirely in R and at the moment deployed on the free shinyapps.io server. This is why it may be a little bit slow or partly not accessible. You can deploy your app on your own, faster server, too (or pay for a faster shinyapps.io option).

Before starting to code the app, you might want to have a look at our tutorial on the graphic package ggplot2 and our guide to tidy data, since we will use some of the functions and principles for it. If you’re already familiar with ggplot2, tidyr and dplyr: Perfect, let’s go!


For those of you who are completley new to shiny, we’ll start with a draft script in RStudio. Here we will install the packages, since the install.packages() function doesn’t work well with a shiny app script. A shiny app loads packages but will give an error when asked to install them.

In the draft script

Now download the emission data and the markdown file emissions_app.Rmd from the shiny repository on our GitHub page. Save them in a directory and name it shiny_app. In the draft R script, set the working directory to this directory and read in the excel file.

If you know the tidy, molten data format, you’ll see right away that this data isn’t tidy yet. Let’s restructure it with tidyr’s gather() function.

Much better! Now, still in the draft script, let’s build a stacked bar chart with ggplot2, showing the emissions for every air pollutant and every year in our data. We don’t have to do this but we can optimize the plot now and paste it into the app later.

This plot should now look almost exactly as the interactive plot in the app. To spread our molten data again so it looks like the table in the app’s table tab, we’ll use the spread-function of tidyr. It basically does the opposite of gather() and we use it because we want the table to display the same input that’s given to the plot but in the spreaded format.

Awww yeah, the backbone of our app content is ready. Let’s get right to the application!


Building the app

A shiny app script basically consists of four parts:
1. preps   The part where required packages and the data are loaded.
2. ui   The user interface is the structuring part of the app. Here the app gets it’s design and divisions.
3. server   Here the app gets it’s content like a plot output etc.
4. shinyApp   This is where the magic happens! With a short command the user interface and the server part are merged to become an awesome shiny app.
First things first: preps = preparations
Open a new R script and only library the packages we installed in the draft.

Next thing is just copy/paste: We simply copy over the draft part where we read in the data and structured it. As soon as you save the script as app.R, RStudio will recognize it as a shiny app and the Run button will magically become a Run App button.

ui = user interface
There are multiple ways to structure your app. We’ll choose a simple design with three panels:


All panels are defined within the shinyUI() function and the fluidPage() function. fluidPage() is a design function for creating fluid pages that scale their components in real time to fit the width of the browser. In short: It makes pages responsive.

The header panel
Like with the whole app, you even have some options to style and divide the panels. Instead of using shiny’s headerPanel() function, we will use the fluidRow() function to divide the header panel into two columns: One with width 10 for the title and one with width 2 for the image. Note that no matter how many columns you want, their widths have to sum up to 12 in the end!

The sidebar panel
The sidebar panel is the part where the user can interact with the data, for example by picking categories. There are different select options like with checkboxes or select lists with a dropdown menu.

The main panel
The main panel is the stage for all the fancy things you code in the server part. Basically, we assign the outputs of the server code their space in the app. If you want to display more than one thing but don’t want your user to scroll and scroll and scroll you may want to add some tabs he can switch to.

That’s it! The styling part is done.

server = well, server
As said, the server part is where we code what is to be shown on the main panel and what should happen when the user interacts with the select panel. The whole server part is defined within the shinyServer() function that takes the input of the user as defined in the user interface and returns the output to it.

reactive data
the most important part is to prepare the data to reactively change when the user changes the input. We enable that with the reactive() function.

Now the data will adapt to the input of the user. On this basis, we can code the different plots we stated in the main panel of the user interface.

Copy our ggplot from the draft and paste it within the renderPlot() function. It’s important to name the output output$mplot since we referred to it as plotOutput(“mplot”) in the main panel of the user interface.
The only thing you need to change when it comes to the ggplot code is the data name and the information for the y-axis scale. Instead of plotting emissions_restructed, we now want to plot the reactive plotdata of the reactive dataset data(). Note the brand new brackets the data got because it’s reactive!

Here we can paste the table code of our draft script and simply add a filter() function to only display those parts of the data the user selected.

Now for the two text outputs. Both are made with the renderUI() function. The first only contains the source with a tagged link. According to the ui-part it will be displayed below the table output.

The text output contains some additional informations on the data and will be displayed above the table as established in the user interface.


shinyApp – the magic happens right here!
Finally, merge the ui and the server part to form one awesome app! If you haven’t saved the file as app.R in the same directory as the emissions data and the markdown file yet: Do it now! The Run button will become a Run App button and you can admire your product!

Awesome, yet simple. If you create an acount at shinyapps.io, you can connect RStudio with it and publish your app right away on a shiny server. If you embed it the right way into your website (and if it doesn’t contain a not responsive, big image like my first app on my blog) your shiny app will be fully responsive. If you have a look at this tutorial with your phone, you’ll see that shiny’s responsive design isn’t perfect yet.

If you coded your very first app with this tutorial or after reading this tutorial, let us know! We would love to see your work and creativity with the shiny application framework!

If you have any questions, problems or feedback, simply leave a comment, email us or join our slack team to talk to us any time!


{Credits for the awesome featured image go to Phil Ninh}

Comments ( 4 )

    • ReplyMarie-Louise Timcke
      Thank you very much for your feedback! I have to admit that I chose the years and particles to be shown without thinking a lot of if it makes sense or not. My focus was on how to build the app and I only saw the data as an example to fill the the code with a little bit life. But you are very right and as we want to provide journalistic knowledge, too, what I did wasn't best practice at all. I added a note on this at the beginning of the tutorial! Best regards and thank you very much, Marie
  1. ReplyEric
    I am building a shinyApp that depends on 2 r scripts I have written. The input for those scripts is on the UI page. How do I get those inputs into the scripts on the Server.page?

Leave a reply

Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.