mercredi 7 juin 2017

How can I use checkboxGroupInput in Shiny to control several reactive layers in a ggplot2 plot efficiently?

I have made three reactive layers in my graph. In the reproducible example below, the graph starts with function1 drawn. If I check function2, shiny recalculates and redraws function1 and function2. Then if I tick function3, all 3 functions are recalculated and redrawn.

Say the functions I want to run are very long inferences that take several minutes each.

How can I make it so that when I check (or uncheck) one function, shiny does not recalculate and redraw all three functions?

In the code below, I have included print statements which show that each reactive layer is recalculated and redrawn each time renderPlot is called. I hope you find the print statements helpful, if not please hash them out.

library(shiny)
library(ggplot2)
x <-  seq(0, 10, by=0.1)

runApp(shinyApp(

  ui = shinyUI(fluidPage(
    titlePanel("Test Shiny"),
    sidebarLayout(
      sidebarPanel(
        checkboxGroupInput("fun", label = "Function", 
                           choices = list("function1: x^2" = 1, 
                                          "function2: x^2 + x" = 2, 
                                          "function3: x^2 - x" = 3),
                           selected = c(1))
      ),
      mainPanel(
        plotOutput("plot")
      )
    )
  )),

  server = shinyServer(function(input, output) {


    fn1 <- reactive({ 
      print("we are in fn1 <- reactive({})")
      if (1 %in% input$fun ) { 
        geom_line(mapping = aes(x, y=x^2), color="blue") }
    })


    fn2 <- reactive({
      print("we are in fn2 <- reactive({})")
      if (2 %in% input$fun)  { 
        geom_line(mapping = aes(x, y=x^2 + x), color="red") }
    })


    fn3 <- reactive({
      print("we are in fn3 <- reactive({})")
      if (3 %in% input$fun) { 
        geom_line(mapping = aes(x, y=x^2 - x), color="green") }
    })

    output$plot <- renderPlot({
      print("we are in output$plot <-  renderPlot({})")
      ggp = ggplot()
      ggp = ggp + fn1() + fn2() + fn3()
      ggp
    })  
  })
))

I can achieve this efficiency using single checkboxes (checkboxInput) but I would prefer not to use single checkboxes. Single checkboxes don’t look as good, unless there is a way to make them look more like checkbox Group Inputs?

I have been trying to work this out and searching SO for some time. I would be very grateful for any help with this!!!




Aucun commentaire:

Enregistrer un commentaire