My Shiny Workflow
Lately I’ve been doing quite a bit of Shiny development. I absolutely love shiny. In fact I find myself building little shiny apps to do just about everything. I’ve developed a bit of a workflow for how I make my apps which has made Shiny easier for me. I thought I’d share this just in case it helps anyone else!
1. Draw a sketch of your finished app
I like to start with a quick drawing of the finished application. Normally this is just a series of boxes showing all the inputs and outputs. It’s also a good idea to decide the names of those inputs and outputs now.
2. Write all your R code and design all your plots first.
A big disadvantage of Shiny is that when things go wrong it can be hard to debug (see step 5!). So I always write out all the R code I’m going to use in the application first. I tend to have all my inputs at the top of the file set to some value like this:
n_apples <- 5
date <- '2016-05-03'
3. Start with ui.R
Since, for me anyway, ui.R is the harder of the two files to create. I often write the whole of ui.R with only a skeleton server.R. Even with nothing in server.R you can still run the app and get an idea of the layout and check for syntax errors. I like not having the ‘switch’ my brain between thinking about the look at the application and the content.
I’m also scrupulous about getting all the indention correct, particularly matching the indentation level of opening and closing brackets. Keeping all the commas and brackets organised was one of my big stumbling blocks when I started.
4. Add code to shiny.R
Use lots of structuring comments in shiny.R, so that you can easily find the piece of code that relates to a piece of the UI. For lots of projects it’s also a good idea to keep code across many files. Remember when source
ing those files to use local = TRUE
. Remember to add brackets to objects that are now reactive, and input$
to all the inputs.
5. Debugging!
No matter how carefully I plan all my code before starting things still always go wrong. The errors that Shiny produces can be a little confusing.
Almost every app I build I end up having a little temporary debugging output in the server above the title:
textOutput('debug'),
And in server:
output$debug <- renderPrint({
# Something you want to inspect here
})
This lets me look at my reactive objects and see how they change with the inputs.
Just remember to delete the debugging section when you are finished with the application.
5. Refine and iterate
Although I’ve drawn a plan at the start the finished app almost never looks like that. I tend to go though a few iterations to get the app how I like. I tend not to add much custom formatting until I’m pretty happy with the layout and the content of the application. Particularly if I’m working with a client I get them to sign off before doing any time-consuming tweaking.
So that’s it! I hope you’ve found some of these tips helpful.