Search code examples
rshinyshinyappsshiny-reactivity

Access values returned by a reactive function without calling the function more than once


My problem is that I want to use the results of a reactive function more than once but this function takes a long time to return its result (a vector).

My code follows the structure below:

ui <- fluidPage(
  
  
  theme = bs_theme(version = 4, bootswatch = "sandstone"),
  
  titlePanel("TITLE"),
  
  sidebarLayout(
    sidebarPanel(
      numericInput("n", "n"),
      numericInput("m", "m"),
      numericInput("sigma", "sigma"),
      numericInput("S2", "S2"),
      numericInput("alpha", "alpha"),
      numericInput("lambda", "lambda"),
      numericInput("beta", "beta"),
      actionButton("runButton", "Run")
    ),
    
    mainPanel(
      tabsetPanel(
        tabPanel("Results and chart", 
                 tableOutput("results"),
                 plotOutput("chart")),
        tabPanel(...)),
        
      )
    )
  )
)

server <- function(input, output) {

  results <- eventReactive(input$runButton, {


  #Code with loops


  #Returns a vector called "data4"
  return(data4)

  })

  output$resultados <- renderTable({
    
    results()
    
  }, rownames = FALSE, sanitize.text.function = function(x) x)
  
}

So I'm using the fuction results(), and it's returning a vector which is beeing rendered as a table. But now I would like to use some values stored in positions of the vector returned by this function as if I was using a variable... is it possible?

I have tried to assign the function to some variable but it doesn't seem to be possible...

I'm new with shiny, and it's the first time I'm posting something in stackoverflow... so I'm sorry if I don't explain as well you need... please let me know if ou need something more to understand the situation.

Thank you in advance!


Solution

  • One way to do it is define a reactiveValues object and assign it the vector of interest only once in an observer. Then use it as you wish. Try this

    ui <- fluidPage(
      
      # theme = bs_theme(version = 4, bootswatch = "sandstone"),
      
      titlePanel("TITLE"),
      
      sidebarLayout(
        sidebarPanel(
          # numericInput("n", "n"),
          # numericInput("m", "m"),
          # numericInput("sigma", "sigma"),
          # numericInput("S2", "S2"),
          # numericInput("alpha", "alpha"),
          # numericInput("lambda", "lambda"),
          # numericInput("beta", "beta"),
          actionButton("runButton", "Run")
        ),
        
        mainPanel(
          tabsetPanel(
            tabPanel("Results and chart", 
                     tableOutput("results"),
                     plotOutput("chart")),
            tabPanel("Other panel")
            )
        )
      )
    )
    
    server <- function(input, output) {
      output$chart <- renderPlot(plot(cars))
      res <- reactiveValues(ults = NULL)
      
      observeEvent(input$runButton, {
      
        #Code with loops
        
        #Returns a vector called "data4"
        # return(data4)
        res$ults <- mtcars[,4]
      },once = TRUE)
      
      output$results <- renderTable({
        
        req(res$ults)
        
      }, rownames = FALSE, sanitize.text.function = function(x) x)
      
    }
    shinyApp(ui, server)