Default value for input generated by reactiveUI

3,144 views
Skip to first unread message

Haider Ali

unread,
Dec 12, 2012, 3:14:00 PM12/12/12
to shiny-...@googlegroups.com
Is there a way to define a default value for a input that will be generated by a reactiveUI ? My example use-case is the following:

* A select input list is generated based on date
* Other reactive functions utilize inputs like date, result of the select input list, etc to generate further results; these functions validate that the input$date, input$selectListInput are of length > 0 and not empty strings; if they are, they will just ignore the inputs and use the appropriate defaults for them

What happens is that, initially, input$selectListInput is undefined so my reactive functions will process and generate some result while the reactiveUI populates values for them. Once reactiveUI is done, because input$selectListInput now has a different value (went from undefined to the default set in my reactiveUI) and forces the other reactive functions to re-eval again. 

The way I got around it for now is that, the main reactive functions don't go any further if the input$selectListInput is length 0 - but this forces me to do additional validation and return a empty data.frame() etc which is visible to the user; however, as soon as the reactiveUI is finished processing, it will then evaluate again with the actual results. 

Alternatively, is it possible to define a default value at startup for reactiveUI components - this way, everything else on the page can be rendered and as long as the default value in the reactiveUI is the same as the initial default value, no further re-eval would be needed. 

Hopefully the question makes sense

Thanks

-Haider

Joe Cheng [RStudio]

unread,
Dec 12, 2012, 4:34:42 PM12/12/12
to shiny-...@googlegroups.com
When the reactiveUI function generates the HTML for selectListInput, you can explicitly tell the selectInput default to be the same as input$selectListInput (although you do have to check for input$selectListInput being NULL). I realize this is a little manual, but I haven't thought of a cleaner way without massively complicating selectInput et al.



-Haider

--
 
 

Haider Ali

unread,
Dec 14, 2012, 8:49:35 AM12/14/12
to shiny-...@googlegroups.com, j...@rstudio.org
Thank's for the quick reply Joe. 

I didn't quite follow your suggestion. I put together a simple app to illustrate what I'm seeing:

ui.R

shinyUI(bootstrapPage(  
  textInput(inputId='nords', label='Random Obs: ', value=10),
  uiOutput("selectInputData")
))

server.R

shinyServer(function(input, output) {

  genListData <- reactive(function()
  {
    print(paste('Generating List Data - input$nords = ', input$nords))    
    c(0, rnorm(input$nords))
  })
  
  output$selectInputData <- reactiveUI(function()
  {
    print('Output SelectInputData Called...') 
    dList = as.list(genListData())
    
    selectInput(inputId='randomList', label='Random Select List', choices=dList, selected=0)
  })
  
  output$nullOutput <- reactive(function() {
    
    print(paste('output$nullOutput func depends on input$randomList - value =', input$randomList))
         
  })
})

The output generated (no UI interaction) is:

R> shiny::runApp('shinyApp/')

Listening on port 8100
[1] "Output SelectInputData Called..."
[1] "Generating List Data - input$nords =  10"
[1] "output$nullOutput func depends on input$randomList - value = "
[1] "output$nullOutput func depends on input$randomList - value = 0"


So my original issue/question had to do with why output$nullOutput is triggered twice - once when input$randomList is null and then second time it contains the default value that I gave in the reactiveUI function. There is no way in the server.R to set input$randomList = 0 initially (it's valid syntax but the change isn't reflected)

I think reactiveUI, nullOutput, etc in the server.R are evaluated all at the same time - so during the first evaluation round, I don't think it matters if you change the input$randomList value in reactiveUI. 

I wonder if there should be a way to initialize reactiveUI components before the server.R evaluates/generates its content - maybe in ui.R 

Hopefully the example makes sense

Cheers

-Haider 

Joe Cheng

unread,
Dec 14, 2012, 10:34:34 AM12/14/12
to shiny-...@googlegroups.com, j...@rstudio.org

Ok I'm with you now. I'd just do:

randomList <- reactive(function() {
  if (is.null(input$randomList))
    0
  else
    input$randomList
})

And have nullOutput read randomList() instead of input$randomList. If this is something you think you'll need a lot you could wrap it up in a nice function.

--
 
 

Haider Ali

unread,
Dec 14, 2012, 11:43:48 AM12/14/12
to shiny-...@googlegroups.com, j...@rstudio.org
That fixes the issue of initialization but still calls nullOutput twice - since originally input$randomList is null and then becomes 0:

R> shiny::runApp('shinyApp/')

Listening on port 8100
[1] "Output SelectInputData Called..."
[1] "Generating List Data - input$nords =  10"
[1] "output$nullOutput func depends on input$randomList - value = 0"
[1] "output$nullOutput func depends on input$randomList - value = 0"

Not a big deal but I think it's a issue if you have expensive db/computation functions that are dependent on input controls rendered by reactiveUI - which would get called twice on every initialization. 

Joe Cheng

unread,
Dec 14, 2012, 12:01:34 PM12/14/12
to shiny-...@googlegroups.com
Actually this is because of a mistake in my randomList implementation, I think if you change 0 to "0" the problem will go away. By reading randomList instead of input$randomList, you're insulated from the changes in input$randomList. When randomList recalculates, if the new value is the same as the previous value, no changes are propagated.


--
 
 

Joe Cheng

unread,
Dec 14, 2012, 12:03:00 PM12/14/12
to shiny-...@googlegroups.com
For completeness: When I say "if the new value is the same as the previous value" I mean identical(old, new) == TRUE.

Haider Ali

unread,
Dec 14, 2012, 12:22:06 PM12/14/12
to shiny-...@googlegroups.com
Nice - I didn't realize the type difference 

So this seems like a reasonable way to go - build a accessor function for any reactiveUI inputs 

Thanks

Marie Vendettuoli

unread,
Jun 21, 2013, 9:37:04 PM6/21/13
to shiny-...@googlegroups.com
is there a reason for not using the all.equal? 

Joe Cheng

unread,
Jun 21, 2013, 11:02:00 PM6/21/13
to shiny-...@googlegroups.com
We are doing exact equality testing, my understanding is identical is the most appropriate function for that. 
--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 


--
Sent from my phone

Marie Vendettuoli

unread,
Jun 21, 2013, 11:12:42 PM6/21/13
to shiny-...@googlegroups.com
when storing certain objects in a reactiveValue, dependence on the identical function may lead to excessive computation.... not terribly difficult to work around, but it may explain some cases where the UI seems to hang up. cheers!

> library(xcms)
> library(faahKO)
> cdfpath <- system.file('cdf',package='faahKO')
> cdffiles <- list.files(cdfpath,recursive=TRUE,full.names=TRUE)
> raw1 <- xcmsRaw(cdffiles[1])
> raw2 <- xcmsRaw(cdffiles[1])
> identical(raw1, raw2)
[1] FALSE
> identical(xcmsRaw(cdffiles[1]), xcmsRaw(cdffiles[1]))
[1] FALSE
> all.equal(raw1, raw2)
[1] TRUE

Joe Cheng

unread,
Jun 22, 2013, 12:34:31 AM6/22/13
to shiny-...@googlegroups.com
Interesting. Perhaps the Shiny reactive equality test needs to be extensible, like with an S3 method...
Reply all
Reply to author
Forward
0 new messages