Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downloading Reactive Objects in Shiny

Tags:

r

shiny

Is it possible to download objects in shiny without having to create a separate, redundant, instance of that object within the downloadHandler() call? For example, consider the following example:

ui.R

library(shiny)

shinyUI(pageWithSidebar(
  headerPanel("Simple Example"),

  sidebarPanel(
    textInput("options","Enter some content:",""),
    submitButton("Go")
  ),

  mainPanel(
    tableOutput("dataTable"),
    downloadButton('downloadData','Save Data as CSV File')
  )
))

server.R

library(shiny)

shinyServer(function(input, output) {
  makeQuery <- reactive({
      if(input$options == ""){
        return("Enter some options")
      }
      else {
        return(input$options)
      }
  })

  runQuery <- function(query){
    dat <- data.frame(v1=rep(query,5))
    return(dat)
  }

  output$dataTable <- renderTable({
    query <- makeQuery()
    if(grepl("^Enter",query)){
      return(data.frame(Error=query))
    } else {
      return(runQuery(query))
    }
  },include.rownames=FALSE)

  output$downloadData <- downloadHandler(
    filename = c('data.csv'),
    content = function(file) {
      write.csv(runQuery(makeQuery()), file)
    }
  )

})

The issue I have with the above example is that I am running runQuery() within both the renderTable() and downloadHandler() calls. In this example there isn't really any extra overhead but in my real example this requires running a 5-10 minute process so it is extremely inefficient to call it twice whenever someone downloads the data.

Is there anyway that I can get around this issue by referencing an already created object in the downloadHandler() call or some other work around?

like image 621
David Avatar asked Jun 24 '13 18:06

David


People also ask

How does reactive work in shiny?

A reactive expression is an R expression that uses widget input and returns a value. The reactive expression will update this value whenever the original widget changes. To create a reactive expression use the reactive function, which takes an R expression surrounded by braces (just like the render* functions).

How do you make a shiny reactive?

You can create reactive output with a two step process. Add an R object to your user interface. Tell Shiny how to build the object in the server function. The object will be reactive if the code that builds it calls a widget value.

What does the renderPlot function do in shiny?

renderPlot is an reactive function that can take input data from the ui. R script and feed it into the server. R script. It then actively updates the information within its function.


1 Answers

Yes! Turn the query from a function that you call from two places, into a reactive expression that you access from two places. Reactive expressions cache their results automatically.

like image 196
Joe Cheng Avatar answered Oct 22 '22 10:10

Joe Cheng