6

In my shiny app, I have two tabs: tab 1 has a checkboxInput and a selectInput that is encoded as a renderUI in server.R and is shown only if the box is checked. In the tab 2, there is a ggvis function to plot a data frame that is made through a reactive function only when selectInput was shown in the tab 1.

Unexpectedly, the selectInput is not shown in the tab 1 unless I click on the tab 2 first and then return back to the tab 1, even though selectInput is only dependent on the checkbox that is in the same tab, i.e. tab 1.

Apparently, I do not get the idea of reactive functions right. Could you please indicate where is my mistake? Thanks!

P.S. The structure is quite complicated, but it is what I need for my "real" app.

ui.R

library(ggvis)

shinyUI(navbarPage("",
                   tabPanel("1",
                              checkboxInput("START", label = "Start calculations", value = F),
                              htmlOutput("SELECT")
                   ),
                   tabPanel("2",
                            ggvisOutput("PLOT")
                   )
))

server.R

library(ggvis)

shinyServer(function(input, output, session) {

  output$SELECT<-renderUI({ 
    if (input$START==T) {
    selectInput("SELECTINPUT","Make your choice:",c(1,2))
    }
  })

  PLOTDF<-reactive({
    if (is.null(input$SELECTINPUT)==F) {
      plotdf<-data.frame(c(1,1,2,2),c(1,2,3,4))
      colnames(plotdf)<-c("X","Y")
      plotdf
    }
  })

  reactive({
    PLOTDF() %>% ggvis(~X,~Y) %>% layer_points
    }) %>% bind_shiny("PLOT")

})
bsierieb
  • 178
  • 1
  • 8
  • The code you posted crashes right away for me. – Matthew Plourde Aug 12 '14 at 14:39
  • That is strange because it works for me (I have also tried to copy-paste it from my message). Do you get any error message? – bsierieb Aug 12 '14 at 14:40
  • Yeah, "No data supplied to mark". Perhaps I have different versions of shiny or ggvis. ggvis: 0.3.0.99; shiny 0.1 – Matthew Plourde Aug 12 '14 at 14:42
  • Just ignore this message. It appears because PLOTDF is needed for the ggvis plot - and just after the start PLOTDF is not yet created. I will later add an "if" condition to the ggvis expression, but at the moment all this does not prevent the code from executing, although a couple of such error messages are shown (at least it works on my machine). – bsierieb Aug 12 '14 at 14:47

1 Answers1

3

Not sure what is.null(input$SELECTINPUT)==F is doing I'm guessing you want something like !is.null(input$SELECTINPUT) also maybe wrap the ggvis call in an observer and check for input

The following works for me:

library(ggvis)
library(shiny)
runApp(list(ui = navbarPage("",
                            tabPanel("1",
                                     checkboxInput("START", label = "Start calculations", value = F),
                                     htmlOutput("SELECT")
                            ),
                            tabPanel("2",
                                     ggvisOutput("PLOT")
                            )
)
, server = function(input, output, session) {

  output$SELECT<-renderUI({ 
    if (input$START==T) {
      selectInput("SELECTINPUT","Make your choice:",c(1,2))
    }
  })
   PLOTDF<-reactive({
    if (!is.null(input$SELECTINPUT)) {
      plotdf<-data.frame(c(1,1,2,2),c(1,2,3,4))
      colnames(plotdf)<-c("X","Y")
      plotdf
    }
  })
  observe({
    if (!is.null(input$SELECTINPUT)) {
    PLOTDF() %>% ggvis(~X,~Y) %>% layer_points%>% bind_shiny("PLOT")
    }
  }) 
}
)
)
jdharrison
  • 30,085
  • 4
  • 77
  • 89
  • that works, thanks a lot! could you please just briefly explain why `reactive` did not work properly? – bsierieb Aug 12 '14 at 14:51
  • 1
    `reactive` expressions use lazy evaluation, when their dependencies change, they don't re-execute right away but rather wait until they are called by someone else. observers use eager evaluation changing as soon as their dependencies change. The `no data supplied to mark` required the if clause and this seemed more natural in an observer. – jdharrison Aug 12 '14 at 15:05