How to run expensive code once at start-up, and then subsequently only on user request

2,245 views
Skip to first unread message

Arthur Small

unread,
Jan 5, 2013, 3:48:45 PM1/5/13
to shiny-...@googlegroups.com
I came up with a little solution to a little problem I encountered, and am sharing it in the thought that others might find it useful and save themselves a bit of time. 

I have some expensive processing that I would like to be performed once at start-up, and then again if and only if the user so requests.  I tried using the new isolate() function that Joe introduced yesterday. His example shows how to keep expensive code from starting up until a specified action button is pressed. The problem: I wanted the code to run exactly once before the action button was pressed, but then subsequently only if and when the action button was pressed.  

Joe's example code wouldn't quite do the trick: an action button's count variable is automatically set initially to zero, so "if(input$buttonValue==0) return(NULL)" won't run my code for me at start up.  (Sidebar note/feature request: It would be nice if it were possible to create action buttons with non-zero initial values.)  

The solution, like so many others, is obvious once you see it: don't use zero as the test value. 

expensiveProcess <- reactive(function() {
  if (input$recalcButton == -1)
    return(NULL)
 
  return(isolate({
      # reset value of action button to prevent further un-requested recomputation of the expensive process
      input$recalcButton <- -1      
 
    # Now do the expensive stuff
    foo <- activateInterlock(input$foo)
    bar <- connectDynotherm(input$bar)
    baz <- bringInfracellsUp(input$baz)
    c(foo=foo, bar=bar, baz=baz)
  }))
})

Some readers may react by thinking, "Well, no duh."  What can I say: it took me a bit to figure it out (employing my currently flu-fogged brain), and thought this structure might be of use to some others.

Regards,

Arthur

Joe Cheng

unread,
Jan 5, 2013, 4:57:48 PM1/5/13
to shiny-...@googlegroups.com
Glad you were able to figure that out. You could also skip the if and return, simply this line would do it:

input$recalcButton
--
 
 


--
Sent from my phone

Vicky Yang

unread,
Jan 10, 2013, 6:54:19 PM1/10/13
to shiny-...@googlegroups.com
This is wired. I am trying something similar. Resetting actionButton value didn't work for me. The value still keeps incrementing to 1,2,3, ..., as the button being clicked continuously. 

Is the button value reset-able? 

Joe Cheng

unread,
Jan 10, 2013, 7:07:34 PM1/10/13
to shiny-...@googlegroups.com
No it's not. I didn't notice that line in Arthur's code snippet. "input$recalcButton <- -1" is not necessary and in fact does nothing.

I don't know why you would need to ever reset the actionButton value.

If you want it to happen on startup and also on every button click:

reactive(function() {
  input$recalcButton
  isolate({
    # do expensive stuff here and return the result
  })
})

If you want it NOT to happen on startup, but only on button click:

reactive(function() {
  if (input$recalcButton == 0)
    return()

  isolate({
    # do expensive stuff here and return the result
  })
})



--
 
 

Quenton Stricklin

unread,
Nov 20, 2014, 3:33:34 PM11/20/14
to shiny-...@googlegroups.com
Is there a new way to do this?

In the console I'm getting :
Passing functions to 'reactive' is deprecated. Please use expressions instead. See ?reactive for more information.

Thanks,
Quenton

Joe Cheng

unread,
Nov 20, 2014, 4:55:25 PM11/20/14
to Quenton Stricklin, shiny-...@googlegroups.com
Instead of "reactive(function() { ... })", now you just do "reactive({ ... })". That should make the message go away.

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/78be0d3b-2651-4334-a7ea-02c6d3b1199e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages