简体   繁体   中英

How to render multiple output from the same analysis without executing it multiple time? (Shiny)

I am writing an shiny app in which contains an stochastic function generates four objects - one plot and three tables. However, I want to render each object in different tabs without being executing the function four times since this stochastic function will generates four different versions. I have been researched online and find a lot people recommend "reactive()" but I still don't quite understand how to apply it to my problem. How can I use those four objects on rendering with only one execution on the function?

My "server.R" structure basically looks like the below:

shinyServer(function(input, output) {

     stochastic_function() {
          ...
       plot1 <- ...
       table1 <- ...
       table2 <- ...
       table3 <- ...
       result <- list(plot, table1, table2, table3)
     return(result)
     }

 output$plot <- renderPlot({

})

 output$table1 <- renderTable({

})

 output$table2 <- renderTable({

})

 output$table3 <- renderTable({

})

...

So, I have tried something like below for the stochastic function:

model <- eventReactive(input$goButton, {
        reactive(WG_Model(cdata = cdata(), # load data from outside env
                          sdata = sdata(), # load data from outside env
                          N = input$n, 
                          end_date = input$end_date,
                          cpx_goal = input$cpx,
                          N_new = input$n2, 
                          end_date_new = input$end_date2,
                          spend_range = input$s_range,
                          spend_incr = input$s_incr
                          ) 
                )
})

The idea is to add an "GoButton" to initiate the function and then save all outputs in a reactive fun(). So I can render each output with:

 output$plot <- renderPlot({
   model$gplot
})

 output$table <- renderTable({
   model$table
})

# Render UI section 
 output$tb <- renderUI({
  tabsetPanel(tabPanel("About Model", plotOutput("plot")), 
              tabPanel("About Model", tableOutput("table")))

  })

However, I only got "Error: object of type 'closure' is not subsettable" in the UI output. Which part did I miss?

If your model() is a list and contains data for all tables and a plot, it should work as in my example.

In this app, after pressing a button, a random number and data for a table and a plot are generated. Then the number, data for table and a plot are returned as a list and rendered with appropriate render* functions.

This app illustrates that the model function won't be re-run after accessing it with model() in other reactive functions.

However, there is an odd thing...the plot is not always rendered. You sometimes have to click the button few times to get the plot. The table is working always.


library(shiny)

ui <- shinyUI(fluidPage(
   br(),
   actionButton("numb", "generate a random numbers"),
   br(),
   br(),
   verbatimTextOutput("text"),
   plotOutput("plot"),
   tableOutput("table")
))

server <- shinyServer(function(input, output) {

  model <- eventReactive(input$numb, {
    # draw a random number and print it
    random <- sample(1:100, 1)
    print(paste0("The number is: ", random))

    # generate data for a table and plot
    data <- rnorm(10, mean = 100)
    table <- matrix(data, ncol = 2)

    # create a plot 
    Plot <- plot(1:length(data), data, pch = 16, xlab ="", ylab = "")

    # return all object as a list
    list(random = random, Plot = Plot, table = table)
  })

   output$text <- renderText({
     # print the random number after accessing "model" with brackets.
     # It doesn't re-run the function.
     youget <- paste0("After using model()$random you get: ", model()$random,
                      ". Compare it with a value in the console")
     print(youget)
     youget
   })

   output$plot <- renderPlot({
     # render saved plot
     model()$Plot
   })

   output$table <- renderTable({

     model()$table
   })
})


shinyApp(ui = ui, server = server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM