3

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.

Konrad
  • 17,740
  • 16
  • 106
  • 167
  • 5
    You should make chrt_demo_dta reactive, e.g., have `chrt_demo_dta <- reactive({subset(dta_la_demo...})` in your server body and then reference it in `renderPlot` and `renderTable` with `chrt_demo_dta()` – Matthew Plourde Jun 05 '15 at 15:12
  • 1
    What about making `chrt_demo_dta` a global variable, using the double arrow <<-, that way you can access it within any function outside the renderPlot – Oscar Jun 05 '15 at 15:14

2 Answers2

1

In the server function of server.R:

# Create reactive object w/in server func
chrt_demo_dta <- reactiveVal()

output$some_plot<- renderPlot({
  chrt_demo_dta.temp <- subset(
    x = dta_la_demo, 
      subset = <<my-conditions>>>)
  # Update the obj within scope of nested function
  chrt_demo_dta(chrt_demo_dta.temp)
})

# Access of the updated obj is now possible in original scope
output$chrt_demo_dta_tbl <- renderTable({chrt_demo_dta()})

See related: Shiny : How to modify reactive object

Joe Flack
  • 866
  • 8
  • 14
0

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.

Irving
  • 24
  • 1
  • IMO, the solution suggested by @Matthew Plourde in the comment above is the way to go, not writing to disk. – JanLauGe Jul 17 '17 at 10:57