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
  • 9,972
  • 17
  • 74
  • 101

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,275
  • 2
  • 20
  • 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 – 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