Search code examples
robjectscopeshinyscoping

Making an object available in Shiny outside renderPlot for renderTable


I'm drafting a simple Shiny App that provides access to a dynamic chart and a corresponding table. The relevant part of the server.R code looks like that:

output$some_plot<- renderPlot({
    # Subset data on change in the indicator selection
    chrt_demo_dta <- subset(x = dta_la_demo, 
                            subset = <<my-conditions>>>)
    # Define the demography chart
    ggplot(data = chrt_demo_dta, aes(x = variable_a, y = variable_b)) +
      geom_line(aes(colour = GEOGRAPHY_NAME), size = 2) +
      theme_bw()}, height = 650, width = 800)

  # Section generating table
  output$chrt_demo_dta_tbl <- renderTable({chrt_demo_dta})

The problem occurs when I try to access the table I get the following error message:

Error in func() : object 'chrt_demo_dta' not found

It appears that the object chrt_demo_dta is created outside the scoping rules of the renderTable. My question is how can I achieve the following:

  1. I want for the chart and the corresponding table to update dynamically upon the selection, hence my idea to embed the subset command in the renderPlot which works
  2. I want to make use of the same subset in a corresponding table. Ideally, I would like to avoid repeating the subset command. As I have the required data frame ready it appears that it is only a matter of accessing it via the renderTable

I'm aware the the code is not fully reproducible but at this stage I'm not necessarily looking for a particular solution but a more generic guidance whether it would be possible to access an object created within one server element from other server element. If the push comes to shove, I could encapsule the subsetting mechanism in a function and call it twice but it seems to be rather messy solution.


Solution

  • The <<- operator may have unwanted consequences. It sends results to the shared environment, where it is visible to all users of the session. Not only will this create a race-condition where they try to over-write each other, it may expose confidential work to others. You have two solutions: 1) repeat the steps in each local environment, 2) write the result to disk with a unique name (e.g. Sys.time() + data hash). Then you can retrieve it when needed elsewhere. Don't forget to delete the saved file though, or your storage will be consumed.