In my shiny app, users give a year, date and weather station of which they want temperature data. Then they click an action button which generates a plot based on a selection of data according to the input.
I used to have no action button, but with each change in input the plot was remade and it all went extremely slow. I also got an error message which showed for 2 secs before the plot appeared. Sometimes first an empty plot showed for a few secs and then the right plot appeared. Lots of weird and slow stuff, so I decided to let the effect of changed input be delayed until a button is clicked.
In my server part of the app, the code for the plot before I had the button looked like this:
output$plotTemp <- renderPlot({
importdata(input$jaartal)
weerstation <- which(weerstations == input$weerstation)
temperatuur(input$datums, weerstation)
})
importdata() and temperatuur() are functions I import via source(script.R) at the start of the app. They import and calculate temperature data and temperatuur() creates a ggplot at the end.
When I inserted the action button, called "button", the code looked like this:
inputJaar <- eventReactive(input$button, {input$jaartal})
inputDatum <- eventReactive(input$button, {input$datums})
inputStation <- eventReactive(input$button, {
weerstation <- which(weerstations == input$weerstation)
})
output$plotTemp <- renderPlot({
importdata(inputJaar())
temperatuur(inputDatum(), inputStation())
})
I'm not sure if this is proper/clean programming. I have little experience and never used actionButton() before. All I know is that things still go very slow, but at least it doesn't recalculate with every change in input. Also the error or empty plot that showed for a few secs never appear again. That's a good start.
When I asked someone if it was possible to speed things up (or have cleaner code) they told me to use isolate(). I read help pages, saw a youtube video and read some blogs. But I can't grab the difference with my current code (except that it's shorter). Anyway, the code with isolate looks like this:
output$plotTemp <- renderPlot({
input$button
isolate({
importdata(input$jaartal)
weerstation <- which(weerstations == input$weerstation)
temperatuur(input$datums, weerstation)
})
})
I don't notice any changes in speed. The plot still only changes after I click the button, but the error that appeared a few secs before the plot in my first version now appears when I open the plot. It dissapears after I click the button. I don't want my users to see an error at the start, they'll think it's not working.
The error says: "x must be of length 1 or 2". I tried to understand en avoid this before I came up with the actionbutton solution, but never found it.
Anyway, with the button but without isolate, it doesn't show, so I started to ignore it...
What's the difference between the 2nd and 3rd code? An explanation "for dummies" about using isolate or not with the actionbutton would also be very welcome.
Any other solutions or tips to improve my code? (good programming practices or so :) )
Thanks in advance!