简体   繁体   中英

In a shiny app how can I let the user choose the filename and directory to download with write.table

This is a follow-up question to this

Now I somehow managed to download the reactive dataframe to my hard drive (!not server or working directory) and append each new entry as new line with write.table .

Interestingly write.csv does not work because it does not allow append argument https://stat.ethz.ch/pipermail/r-help/2016-August/441011.html .

With this minimal working app, I would like to know how I can get the user to choose a directory and a filname to download there. Now I have this absolut path: file = "C:/Users/yourname/Downloads/my_df.csv" which works. But I don't know if it will work for other user!

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
  sidebarLayout(
    
    sidebarPanel(width = 4,
                 sliderInput("a", "A", min = 0, max = 3, value = 0, width = "250px"),
                 actionButton("submit", "Submit")
                 ),
    
    mainPanel(
      titlePanel("Sliders"),
      tableOutput("values")
    )
  )
)
server <- function(input, output, session) {
 
  sliderValues <- reactive({
    data.frame(Name = c("A"), Value = as.character(c(input$a)), stringsAsFactors = FALSE)
  })
  
  output$values <- renderTable({
    sliderValues()
  }) 
  
  # Save the values to a CSV file on the hard disk ----
  saveData <- reactive({write.table(sliderValues(), file = "C:/Users/yourname/Downloads/my_df.csv", col.names=!file.exists("C:/Users/yourname/Downloads/my_df.csv"), append = TRUE) })
  
  observeEvent(input$submit, {
    saveData()
  })
}
shinyApp(ui, server)

The requirement is that the user should see a modal dialog ui with the question "In which folder with which filename you want to download?". Quasi like the things we do daily if we download from the inte.net.

I now solved it this way:

I realized that I have two options:

  1. As suggested by @Stéphane Laurent using downloadhandler
  2. Using DT::datatable()

I have decided to use number 2. Many thanks to all of your inputs!

library(shiny)
library(shinyWidgets)
library(DT)

ui <- fluidPage(
  sliderInput("a", "A", min = 0, max = 3, value = 0, width = "250px"),
  titlePanel("Sliders"),
  dataTableOutput("sliderValues", width="450px")
)
server <- function(input, output, session) {
  
  sliderValues <- reactive({
    df <- data.frame(
      Name = "A", 
      Value = as.character(c(input$a)), 
      stringsAsFactors = FALSE) %>% 
      pivot_wider(names_from = Name, values_from = Value)
    
    return(df)
  })

  
  # Show the values in an HTML table in a wider format----
  output$sliderValues <- DT::renderDataTable({
    DT::datatable(sliderValues(),
                  extensions = c('Buttons'),
                  options = list(
                    dom = 'frtBip',
                    buttons = list(list(extend = 'excel', filename = paste0("myname-", Sys.Date())))
                  )
    )
  })

}
shinyApp(ui, server)

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM