D3 and R, a match made in heaven
By: Kendon Darlington
Tags: R, Data Visualization, JavaScript, Data Science, D3js

Step 4: Build the back end

The server function is the best part of every Shiny app. This is where you get to do data science. This is also where you paste code from stack overflow and hope it works. Now that I think about it, those two things are the same.

Before we get started building the server function, lets look at our dataset. in the RStudio console, type this and hit enter:

Below are the results. This is the mpg dataset. We are going to take this dataset which has 234 rows and get the average city mpg for each manufacturer. This will get us down to 15 rows of data that we will graph. See the ‘class’ field (compact, suv, etc. )? This is the field we are going to hook up to our dropdown in the ui function. When the user selects ‘suv’, our server function will filter the data to just the manufacturers that produce suv’s.

Image by author

We will acomplish this grouping and aggregation using R’s wonderful Tidyverse library. I don’t want to dive too deep into a lesson on how to slice and dice data with the Tidyverse, that is worthy of an article all on its own. I’m just going to show you the code and briefly describe how this works. Run this from the console:

Results:

Image by author

What is this code doing? Its actually pretty simple. This is Tidyverse syntax, and it reads from top to bottom. The “%>%” syntax is how the Tidyverse library chains the current state of the code block to the next. You can think of it as ‘and then do this…’. In English it is:

Take the mpg dataset.

Filter to where the records in the class column = 'suv'.

Create a new column called avgCity that is the average of city mpg

Reduce the columns to just manufacturer and avgCity

Remove all duplicate records

Rename manufacturer to 'name' and avgCity to 'value'

Now that you understand this, its time to show you the full code for the server function in Shiny.

The final server function

Let me explain this from the top down.

By default, the server function has only input and output. I had to add session to this list of parameters. The session parameter will allow Shiny to send information from the server function to the web page. In our case, we are trying to get our data from R to our JavaScript code in the www folder. This parameter is what makes that happen.

The observeEvent function is monitoring our dropdown in our ui function, recall that we gave it an inputId of ‘vehicleClass’. If the dropdown changes (say from ‘suv’ to ‘compact’), this observeEvent function will notice this change, invalidate the current state of affairs, and rerun this block of code to determine the new state of affairs. Ultimately it will update our D3 graph.

The next block of code is the same as the Tidyverse example we ran above, with one small change:

Rather than hardcode class to ‘suv’, we map it to the vehicleClass dropdown. When you change the dropdown from compact to suv, our filter for the mpg dataset also changes.

Now we use the jsonlite library. This simply takes the state of our aggregated and filtered data, and gets it into a json format. D3 likes json, so we like json.

Now THIS is the magic sauce! This little line of code takes our json payload, and sends it across the session so that it can be consumed by our D3 JavaScript! R is sending a message to our www folder, saying “Yo! here is the data! do something wonderful with it!!”

Finally we have this little bit of code. Recall that our UI function has this uiOutput(“d3”)? Well the same way we can send information from the ui to the server (through input$id syntax), we can also send information from the server to the ui. in this case, we create an object named “output$d3” which is just an html line saying, “render this JavaScript code in the web page”. The name of the script is “script.js”, which is what we named or D3 script!

Now this example wont run just yet. Even though R is now sending our data in a json format over to our D3 script, our D3 script isn’t yet configured to accept it. Only now are we finally ready to venture into the deep dark forest known as D3.

Here is our finished app.R: