Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shiny R - download the result of a table

Tags:

r

download

shiny

I am new to Shiny and I have created a really simple shiny app:

library(shiny)

ui <- fluidPage(
  fluidRow(column(7,dataTableOutput('dto')))
)

server <- function(input,output){

  output$dto <- renderDataTable({MYTABLE})


}

runApp(list(ui=ui,server=server))

Is there any way to put an option to download the result of the table (doesn't matter if is CSV, XLSX...)

cheers

like image 335
jmarco10 Avatar asked Jun 12 '17 16:06

jmarco10


People also ask

Do companies use R Shiny?

Fortune 500 companies trust Appsilon to build custom Shiny apps, scale PoCs, improve Shiny app performance, and enhance dashboard UI. We're also a pioneer in Shiny open source. Our R packages are actively used by global organizations such as Merck, Johnson & Johnson, WHO, Ubisoft, Bank of America, and Renault.

Is R Shiny easy?

On the other hand, R Shiny is an open-source package for building web applications with R. It provides a robust web framework for developing any sort of app, not only dashboards. Shiny is easy and intuitive to use, as you'll see in the examples below.

Is R Shiny a visualization tool?

Shiny is designed for fully interactive visualization, using JavaScript libraries like d3, Leaflet, and Google Charts.


2 Answers

A slightly alternative solution based directly on the datatable / DT extension buttons.

I am shamelessly borrowing the example data from Joris...

library(shiny)
library(DT)

ui <- fluidPage(
 # This one is linked by the id 'download'
  fluidRow(column(7,dataTableOutput('dto')))
)

server <- function(input,output){
  # Reactive expression with the data, in this case iris
  thedata <- reactive(iris)

#the extensions parameter coupled with the options list does the trick  
output$dto <- renderDataTable(thedata(), extensions = 'Buttons', 
                options = list(dom = 'Bfrtip',
                buttons = c('copy', 'csv', 'excel', 'pdf', 'print'))
  )
}

runApp(list(ui=ui,server=server), launch.browser=TRUE) #now runs by default in the external browser.

This will work with different outputs and personally I like the cleaner look. Just make sure that you are running the demo in the external browser. Otherwise it won't work.

like image 86
Buggy Avatar answered Oct 10 '22 16:10

Buggy


That's pretty easy with downloadButton() or downloadLink() in combination with downloadHandler if you make the data itself a reactive expression. Then you can download whatever you send to output using the same reactive expression.

A small example:

library(shiny)

ui <- fluidPage(
  # This one is linked by the id 'download'
  downloadButton('download',"Download the data"),
  fluidRow(column(7,dataTableOutput('dto')))
)

server <- function(input,output){
  # Reactive expression with the data, in this case iris
  thedata <- reactive(iris)

  output$dto <- renderDataTable({thedata()})
  output$download <- downloadHandler(
    filename = function(){"thename.csv"}, 
    content = function(fname){
      write.csv(thedata(), fname)
    }
  )

}

runApp(list(ui=ui,server=server))

Keep in mind:

  • the argument content of downloadHandler must be a function producing a file! It should take one argument for the connection/file name. In this example it is a csv file, but for eg images you can use png() and dev.off(), for ggplots you can use ggsave(), ...
  • the argument filename does not have to be a function, but I found it works better that way. Especially when working with reactive expressions for the file name.
  • you link the downloadHandler and the downloadButton through the output list: the id of downloadButton is the name of the output element returned by downloadHandler.

EDIT:

Some people try to use download.file() for this, but that's wrong as well. The function download.file() works when used on the user side, not the server side. It lets you download files from the internet to the computer that is calling the function. If you'd use that in a Shiny application, it would work when run locally. That's because user and server are the same machine. However, when deploying your app on a Shiny Server, download.file() would essentially be downloading files TO the server, not from.

like image 24
Joris Meys Avatar answered Oct 10 '22 14:10

Joris Meys