2

I have a dataframe df1, and subset it to df1sub and display it in an R shiny renderPlot() call. Similarly, I have df2, and I subset it to df2sub, and render it in R shiny via a separate renderPlot() call. Btw these subsets are created based on user choices in an R Shiny app.

Now, I have a datatable that I want to change to reflect whatever the current dataset is, so I wanted some kind of global like:

buffers[1] <- df1sub
buffers[2] <- df2sub

How would I go about defining this global var? I tried separately doing buffers = array() to initialize a global var but then the assignments as I wrote them above don't work?

Update: attempts to use the the '<<-' operator as suggested below yields the following:

buffers <- NULL #don't know how else to initialize. array() yields same error as below.
buffers[1] <<- df # Error in buffers[1] <<- df : object 'buffers' not found
rstruck
  • 1,174
  • 4
  • 17
  • 27
  • If the data changes should be available in other reactive functions as well you might want to look at `reactiveValues` [here](http://shiny.rstudio.com/reference/shiny/latest/reactiveValues.html) – Vincent Jan 26 '15 at 23:35
  • duplicate of http://stackoverflow.com/questions/15327506/r-shiny-how-to-save-input-data-to-the-server-or-access-input-variables-globally ? – WetlabStudent Jan 27 '15 at 01:40

1 Answers1

0

You can adopt this approach:

library(shiny)

shinyServer(function(input, output) {

  ...
  some.reactive.expression <- reactive1({
     ...
     buffers[1] <<- df1sub
     buffers[2] <<- df2sub
     ...
  })
})

With some updates:

#In global.R
buffers <- list()
buffers[[1]] <- data.frame()
buffers[[2]] <- data.frame()
buffers[[1]] <- df1 #original dataset, as a default, before subsets are created
buffers[[2]] <- df2 #ditto.

Then in server.R:

r1 <- reactive({
... #create subset of df, then return it
buffers[[1]] <<- subset(...)
buffers[[1]] #return it as dynamic data for plots
})

r2 <- reactive({...}) #ditto

then in renderplot:

output$blah <- renderplot(r1()...)
output$foo <- renderplot(r2()...)

Leaving the global buffers[] var separately available to a 3rd UI widget (e.g. a data table)...

rstruck
  • 1,174
  • 4
  • 17
  • 27
Marat Talipov
  • 13,064
  • 5
  • 34
  • 53
  • wow... I have literally never come across that operator till now, and had to google it :-) I'm going to try this out and will come back soon to accept answer... – rstruck Jan 26 '15 at 21:59
  • Quick Q: does doing 'df <- buffers[1]' inside renderPlot() defeat the object? i.e. will it try to do copy by value at that point? nm... just tried it. I get an error saying 'ERROR:argument is of length zero' – rstruck Jan 26 '15 at 22:13
  • I guess it could happen because `buffers` is a vector. Could you try `buffers <- list()` and `buffers[[1]] <<- df1sub; buffers[[2]] <<- df2sub` instead? – Marat Talipov Jan 27 '15 at 18:06
  • no joy there either... with list() it does not work, but it looks promising: at least now I start with a list of length 0. I am learning a lot from all your examples, lol. UPDATE: list() I tried assigning buffers[[1]] <- data.frame() first. This works with the regular assignments, but not with the '<<-' operator. – rstruck Jan 27 '15 at 18:31
  • That's weird... I'm not sure if I have any ideas until I see the actual code. – Marat Talipov Jan 27 '15 at 18:37
  • This is what worked: used '<-' in a global.R to define and set initial values using list(), data.frame(). in server.R, I then used the '<<-' to assign dynamic subsets to the global df list. this was inside a reactive() function like you have shown above. The last step is to make the reactive function return the subset: 'buffers[[x]]'. I could then just use the reactive expression directly to generate dynamic plots. You have helped a lot... I can accept your answer even though it is not exact? – rstruck Jan 27 '15 at 18:59
  • Glad to help. About up-voting -- it's really up to you, I don't take these things very seriously ) – Marat Talipov Jan 27 '15 at 19:17