Shiny (R): Download selection in selectInput to local machine - r

I am trying to create a shiny app where users can view a list of files in the directory, select one of the files, and then download it to their computer. I may be over-complicating this, but I can't seem to find a solution.
ui.R
filenames <- list.files(path=".",pattern="\\.txt")
shinyUI(navbarPage("Download page",
tabPanel("Download",
sidebarLayout(
sidebarPanel(
selectInput("filenames", "Select the file you want to download:", filenames), downloadButton('downloadData', 'Download')
),
mainPanel(
p("Preview of sheet."),
tableOutput('table')
)))))
server.R
library(shiny)
shinyServer(function(input, output) {
datasetInput <- reactive({
switch(input$filenames,
filenames)
})
output$table <- renderTable({
datasetInput()
})
output$downloadData <- downloadHandler(
filename = function() { paste(input$dataset, '.csv', sep='') },
content = function(file) {
write.csv(datasetInput(), file)
}
)})
When I run the app, I can view the list of files in my directory, but the download function does not result in the selected file being downloaded.

Assuming a bunch of 'csv' files in your working directory the code below will list and preview the 'csv' files and download the selected file to your desired directory.
ui.R
shinyUI(navbarPage("Download page",
tabPanel("Download",
sidebarLayout(
sidebarPanel(
selectInput("filenames", "Select the file you want to download:", list.files(pattern = '.csv')),
downloadButton('downloadData', 'Download')),
mainPanel(
p("Preview of sheet."),
tableOutput('table')
)))))
server.R
library(shiny)
shinyServer(function(input, output) {
datasetInput <- reactive({
switch(input$filenames,
filenames)
})
output$table <- renderTable({
read.csv(input$filenames, header=TRUE)
})
output$downloadData <- downloadHandler(
filename = function() {input$filenames},
content = function(file) {write.csv(read.csv(input$filenames, header=TRUE),file)}
)})

Related

Is there an equivalent to the Shiny fileInput function for saving outputs?

Shiny has a nice fileInput() function for allowing the user to browse directories and select the file to upload into the App. Extracted from https://shiny.rstudio.com/reference/shiny/1.7.0/fileInput.html, here's the MWE:
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file1", "Choose CSV file to upload", accept = ".csv"),
checkboxInput("header", "Header", TRUE)
),
mainPanel(
tableOutput("contents")
)
)
)
server <- function(input, output) {
output$contents <- renderTable({
file <- input$file1
ext <- tools::file_ext(file$datapath)
req(file)
validate(need(ext == "csv", "Please upload a csv file"))
read.csv(file$datapath, header = input$header)
})
}
shinyApp(ui, server)
I'm using this in my App for retrieving data, I really like it. However, I'm looking for a similar feature where the user can save a dataframe that results from running the App in a similar way, by browsing directories to choose a location to save the file and selecting a file name. Key is the ability to browse local directories. Any ideas how to accomplish this? Preferably in a way as simple as fileInput().
Files will be .csv, though I'm thinking about .xls too.
You can use downloadButton in ui and downloadHandler in server as follows:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file1", "Choose CSV file to upload", accept = ".csv"),
checkboxInput("header", "Header", TRUE),
downloadButton("download")
),
mainPanel(
tableOutput("contents"),
)
)
)
server <- function(input, output) {
output$contents <- renderTable({
file <- input$file1
ext <- tools::file_ext(file$datapath)
req(file)
validate(need(ext == "csv", "Please upload a csv file"))
read.csv(file$datapath, header = input$header)
})
output$download <- downloadHandler(
filename = function() {
paste0(input$file1, ".csv")
},
content = function(file) {
write.csv(contents(), file)
}
)
}
shinyApp(ui, server)
Here's a really basic example that invokes file.choose when you click on the action button.
library(shiny)
shinyApp(
ui =
fluidPage(
textInput(inputId = "txt_to_save",
label = "Enter text to save to a file"),
actionButton(inputId = "btn_save_txt",
label = "Save Text to File")
),
server =
shinyServer(function(input, output, session){
observeEvent(
input$btn_save_txt,
{
dest_file <- file.choose()
write(input$txt_to_save,
dest_file)
}
)
})
)
In practice, if you wanted to have the file name created by the application, but the directory chosen by the user, you could also use choose.dir().

R Shiny openxlsx: uploaded xlsx file - select a sheet from drop-down menu

In my Shiny app, I can upload an xlsx file and select sheet by typing the sheet's name:
library(shiny)
library(openxlsx)
runApp(
list(
ui = fluidPage(
titlePanel("openxlsx - choose sheet"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose xlsx file',
accept = c(".xlsx"))),
mainPanel(tableOutput('contents'),
textInput("tab1", "Type in sheet name:", "Sheet1")))),
server = function(input, output,session){
output$contents <- renderTable({
inFile <- input$file1
if(is.null(inFile))
return(NULL)
file.rename(inFile$datapath,paste(inFile$datapath, ".xlsx", sep=""))
read.xlsx(paste(inFile$datapath, ".xlsx", sep=""), sheet=input$tab1)
})}))
I would prefer to be able to use a drop-down menu to select a sheet. I know I can use openxl package to get the sheets names, but I am not sure how to implement that in Shiny. Any help will be appreciated.
In the UI:
uiOutput("dropdownUI")
In the server:
Workbook <- eventReactive(input$file1, {
loadWorkbook(input$file1$datapath)
})
Sheets <- eventReactive(Workbook(), {
names(Workbook())
})
output$dropdownUI <- renderUI({
req(Sheets())
selectInput("sheet", "Choose a sheet", Sheets())
})
Dat <- eventReactive(input$sheet, {
read.xlsx(Workbook(), sheet = input$sheet)
})
output$contents <- renderTable({
req(Dat())
Dat()
})

R Shiny, apply an implemented function on a data taken as input

I would like to implement an App which takes a .csv file as input (the user selects the file from his computer), then I want to take this file as a parameter in a function "f" that I've implemented previously.
I can give you the ui.R and server.R
ui.R
library(shiny)
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file",
"Put your portfolio data here",
accept=c(".csv")
)
),
mainPanel(tableOutput("table"))
)
))
server.R
library(shiny)
shinyServer(function(input, output) {
data <- reactive({
file1 <- input$file
if(is.null(file1)){return()}
read.csv2(file=file1$datapath)
})
#to view the data
output$table <- renderTable({
if(is.null(data())){return ()}
data()
})
})
Finally my function "f" is supposed to give a .csv file as output.
ui.R
library(shiny)
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file",
"Put your portfolio data here",
accept=c(".csv")
),
downloadButton(download_data.csv, "Download File")
),
mainPanel(tableOutput("table"))
)
))
server.R
shinyServer(function(input, output) {
data <- reactive({
file1 <- input$file
if(is.null(file1)){return()}
read.csv2(file=file1$datapath)
})
#to view the data
output$table <- renderTable({
if(is.null(data())){return ()}
data()
})
# to download the tadata
output$download_data.csv <- downloadHandler(
filename = "download_data.csv",
content = function(file){
data <- data() # At this point you should have done the transformation
# to the data
write.csv(data, file, row.names = F)
}
)
})

How to download data directory from www directory of shiny

I would like to provide a link to the user to download a list of test data files stored in WWW directory of my shiny app. I tried something displayed below.
library(shiny)
# server.R
server <- function(input, output) {
output$downloadData <- downloadHandler(
filename = 'data',
content = function(fname) {
testdata
})
}
# ui.R
ui <- shinyUI(fluidPage(
titlePanel('Downloading Data'),
sidebarLayout(
sidebarPanel(
downloadLink ('downloadData', 'Download')
),
mainPanel()
)
)
)
shinyApp(ui = ui, server = server)
However, it does not work. How to do.
There is main question how you read data? how you get testdata?
for example if you have data.csv in your www
shinyServer(function(input, output) {
testdata=read.csv2('www\\data.csv',header = F)
output$downloadData <- downloadHandler(
filename =function() { 'data.csv'},
content = function(file){
fname <- paste(file,"csv",sep=".")
write.csv2(testdata,fname)
file.rename(fname,file)
}
)
})
for me work only in browser
You can also try to create zip of all files( cant test zip not work on my R)
shinyServer(function(input, output) {
wd=getwd()
testdata=c("data.csv","data1.csv")
testdata_full_path=path.expand(paste0(wd,"\\www\\",testdata))
output$downloadData <- downloadHandler(
filename = 'data.zip',
content = function(fname) {
tmpdir <- tempdir()
lapply(testdata_full_path,function(i) file.copy(i,tmpdir))
setwd(tmpdir)
zip('data.zip',files= testdata)
setwd(wd)
unlink(tmpdir)
},
contentType = "application/zip"
)
})

Error: Not a graph object in R shiny

Does anyone how to fix this error when I'm trying to find the degree of each vertex from the input file? Here's the Pajek file i want to import in and export the degree into CSV.
When I tried using a smaller input file. The renderTable works but when I tried with my file(which is in the link) it somehow keeps showing that error message and does not display on the tab set.
Here's what I've done so far:
ui.R
shinyUI(fluidPage(
titlePanel("Finding most influential vertex in a network"),
sidebarLayout(
sidebarPanel(
fileInput("graph", label = h4("Pajek file")),
downloadButton('downloadData', 'Download')
),
mainPanel( tabsetPanel(type = "tabs",
tabPanel("Table", tableOutput("view"))
)
)
)
))
server.R
library(igraph)
options(shiny.maxRequestSize=-1)
shinyServer(
function(input, output) {
filedata <- reactive({
inFile = input$graph
if (!is.null(inFile))
read.graph(file=inFile$datapath, format="pajek")
})
Data <- reactive({
df <- filedata()
vorder <-order(degree(df), decreasing=TRUE)
DF <- data.frame(ID=as.numeric(V(df)[vorder]), degree=degree(df)[vorder])
})
output$view <- renderTable({
Data()
})
output$downloadData <- downloadHandler(
filename = function() {
paste("degree", '.csv', sep='')
},
content = function(file) {
write.csv(Data(), file)
}
)
})
Also, I'm also not sure how to write to csv file from the data frame I've output.

Resources