Search code examples
rdataframedownloadshinyshiny-server

Download Handler with reactive datatable (R Shiny)


I have simplified a lot the shiny app I'm trying to build, but, in the idea, I have two functions :

choose_input <- function(n1,n2,n3){
x1 <<- n1+n2
x2 <<- n2+n3
x3 <<- (n1*n2)/n3
}

createmydata <- function(n){
 c1 <- c(1:n)
 c2 <- c1+(x2*x3)
 c3 <- c2+x1

 df <- data.frame("column1"=c1,"column2"=c2,"column3"=c3)

 return(df)
}

You'll tell me that I can do simply one function with these two because they are very simple, but in my app there are a lot of lines and I have to separate the two. Anyway, here is my simulated code :

ui <- fluidPage(
 numericInput("n1",label="Choose the first parameter",min=0,max=100,value=3),
 numericInput("n2",label="Choose the second parameter",min=0,max=100,value=4),
 numericInput("n3",label="Choose the third parameter",min=0,max=100,value=5),
 numericInput("n",label="Choose dataframe length",min=1,max=10000,value=100),
radioButtons("filetype", "File type:",
           choices = c("csv", "tsv")),
downloadButton('downloadData', 'Download'),
tableOutput("data")
)

server <- function(input,output){
  RE <- reactive({
  choose_input(input$n1,input$n2,input$n3)
  createmydata(input$n)
   })

 output$data <- renderTable({
RE()
 })

output$downloadData <- downloadHandler(

filename = function() {
  paste(name, input$filetype, sep = ".")
},

content = function(file) {
  sep <- switch(input$filetype, "csv" = ",", "tsv" = "\t")

  write.table(RE(), file, sep = sep,
              row.names = FALSE)
}
)

}

 shinyApp(ui = ui, server=server)

As you can see, I'd like to download the output table to a csv or excel file... I let you try the code and then try to click on the download button, it does not work...


Solution

  • Debugging

    When I run the code up above and attempted to download the data set, I received the following warning and error message in the Console Pane within RStudio.

    Warning: Error in paste: object 'name' not found
    Stack trace (innermost first):
        1: runApp
    Error : object 'name' not found
    

    This led me to examine the paste() function used within the filename argument in shiny::downloadHandler(). In your code, you use the object name without ever assigning it a value.

    I replaced name with the text "customTable" within the filename argument inside of downloadHandler().

    output$downloadData <- downloadHandler(
    
        filename = function() {
          paste( "customTable", input$filetype, sep = ".")
        },
    
        content = function(file) {
          sep <- switch(input$filetype, "csv" = ",", "tsv" = "\t")
    
          write.table(RE(), file, sep = sep,
                      row.names = FALSE)
        }
      )
    

    Downloading Data in Browser

    After running the app.R script, I clicked on the Open in Browser button to view the Shiny app in a new tab on Chrome. Once there, I was successfully able to download both a .csv and .tsv file after hitting the download button.

    Note: I'm looking for a better reason as to why this action needs to occur, but for now, I came across this relevant SO post Shiny app: downloadHandler does not produce a file.