9

Let's say I have the following server.R file in shiny:

shinyServer(function(input, output) {
  output$plot <- renderPlot({
    data2 <- data[data$x == input$z, ]  # subsetting large dataframe
    plot(data2$x, data2$y)
  })
   output$table <- renderTable({
     data2 <- data[data$x == input$z, ]  # same subset. Oh, boy...
     summary(data2$x)
   })
})

What can I do in order to not have to run data2 <- data[data$x == input$z, ] within every render call? If I do the following, I get a "object of type 'closure' is not subsettable" error:

shinyServer(function(input, output) {
  data2 <- reactive(data[data$x == input$z, ])
  output$plot <- renderPlot({
    plot(data2$x, data2$y)
  })
  output$table <- renderTable({
    data2 <- data[data$x == input$z, ]
    summary(data2$x)
  })
})

What did I do wrong?

Waldir Leoncio
  • 10,853
  • 19
  • 77
  • 107

1 Answers1

19

data2 is a function which returns the subset you are looking for. So you need to call data2 and save the output to some variable then you can plot/summarize the various columns

## data should be defined somewhere up here or in global.R

shinyServer(function(input, output) {
  data2 <- reactive(data[data$x == input$z, ])

  output$plot <- renderPlot({
    newData <- data2()
    plot(newData$x, newData$y)
  })

  output$table <- renderTable({
    newData <- data2()
    summary(newData$x)
  })
})

If you haven't already, I recommend reading through http://rstudio.github.io/shiny/tutorial/#welcome. The page on reactivity addresses this question fairly well.

Jake Burkhead
  • 6,435
  • 2
  • 21
  • 32
  • Thanks for the help, I'm very new to Shiny (it's my second day working with it). Your solution works, but not when I inset a `ifelse()` inside my subset routine, which is actually something like this: `data2 <- reactive(ifelse(input$z == '', data, data[data$x == input$z, ]))`. When I do this, I get the following error: `Error in plot.window(xlim, ylim, log = log, ...): need finite 'xlim' values`. – Waldir Leoncio Jul 16 '13 at 18:47
  • BTW, I'm through with the RStudio tutorial (at least the basic parts) and intend to dig deeper into it and the package documentation with time. – Waldir Leoncio Jul 16 '13 at 18:48
  • 3
    @wleoncio that error is almost certainly because you are passing an empty `data.frame` to plot. So I would suggest doing some debugging to figure out if `data2` returns what you expect. You could also add in checks in your plot output function like `if (nrow(newData) == 0) return()` which will keep it from trying to plot if there is no data. While I'm working on a shiny app, I like adding a table, to be commented out later, that will just print different debugging values (ie number of rows in current data, levels of a certain variable, etc.) – Jake Burkhead Jul 16 '13 at 18:57