I want a user to download a file which is in tabular format with header along with two search widgets on top. The output is forecasted values along with 80%(High-low) and 95%(High-low) confidence interval.So there are five columns, five rows(default). However, i am having two challenges here.
Challenge 1:
When I run the app, after clicking on "Download the file" filename is coming as download data with no extension whereas I have mentioned filename should be "forecasted" with png extension and it should come as forecated.png
Challenge 2: After typing png as extension while saving the file, the file is saved but nothing gets printed.
I have searched in various forums and try to replicate them but nothing seems to be working.
Please suggest.
shiny UI
library(shiny)
downloadButton(outputId = "downloaddata" ,label ="Download the file"),
shiny server
output$downloaddata<-downloadHandler(
filename = function(){
paste("forecasted","png",sep=",")
},
content = function(file){
png(file)
h <-input$fst
tab<-forecast(Model_mape(),h)
datatable(as.data.frame(tab), options = list(
columnDefs = list(list(targets = c(1, 3), searchable = FALSE)),
pageLength = 10))
dev.off()
}
)
Maybe it could help you (it's a simple instance):
Ui :
library(shiny)
shinyUI(fluidPage(
mainPanel(plotOutput("plot1"),
downloadButton("downloadplot","Download your plot"))
))
Server :
library(shiny)
shinyServer(function(input, output) {
your_plot = function(){
(plot(rnorm(1000,0,1)))
}
output$plot1 <- renderPlot({
your_plot()
})
output$downloadplot <- downloadHandler(
filename = "plot_exemple.png",
content = function(file) {
png(file, width = 1200, height = 800)
print(your_plot())
dev.off()
})
})
With this, you can easily download a png (open it in a browser).
Related
I'm working on a Shiny app, in which the user uploads a file, which is then processed to generate a report, which the user can download as an editable Word .doc.
It works as intended, other than that although a "Save As" dialogue window appears which seems to allow you to choose the destination directory, the resulting .doc file ends up being saved to a temporary directory with a randomly-generated name (this is under Windows).
I suspect this is due to the use of the tempdir command, which is part of using rmarkdown to generate the downloaded file.
How should the below code be amended to allow the destination folder to be chosen?
#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(shiny)
library(knitr)
# Define UI for application that draws a histogram
ui <- fluidPage(
uiOutput('markdown'),
# Application title
titlePanel("Apptitle"),
# Sidebar with file input
sidebarLayout(
sidebarPanel(
fileInput(
inputId = "file1",
label = "Select file(s)",
multiple = TRUE,
accept = NULL,
width = NULL,
buttonLabel = "Browse...",
placeholder = "No file(s) selected"
),
downloadButton("report", "Generate report")
),
)
)
server <- function(input, output) {
output$report <- downloadHandler(
reactive(file <- input$file1),
filename = "wordreport.doc",
content = function(file) {
tempReport <- file.path(tempdir(), "wordreport.Rmd")
file.copy("wordreport.Rmd", tempReport, overwrite = TRUE)
params <- list(report.data = input$file1)
rmarkdown::render(tempReport, output_file = "wordreport.doc",
params = params,
envir = new.env(parent = globalenv()))
})
}
shinyApp(ui = ui, server = server)
Thank you for your help!
EDIT: Fixed, using the solution below, and the code edits suggested here: Passing a dataframe as a parameter from Shiny app to RMarkdown
You're passing reactive(file <- input$file1) as the contentType argument to downloadHandler(), which can't be good. Also, you're not writing anything to the file given as an argument to the content function.
Remove the reactive(file <- input$file1) line, and specify output_file = file in rmarkdown::render(), and your download should work.
As discussed in the comments, you won't be able to have control over the download path though -- that's something the user's web browser and their settings there will decide.
Here's a somewhat more minimal app with a functioning file download, for reference:
library(shiny)
ui <- fluidPage(
sliderInput("value", "Some value", 1, 5, 2),
downloadButton("report", "Generate report")
)
server <- function(input, output) {
output$report <- downloadHandler(
filename = "wordreport.doc",
content = function(file) {
params <- list(value = input$value)
rmarkdown::render(
system.file("examples/knitr-minimal.Rmd", package = "knitr"),
output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
}
shinyApp(ui, server)
I'm trying to download my datatable into, a csv. file. Unfortuantely, even though the download starts, it's stuck with calculating and doesn't save the data. The file size is 8mb large and I only could workaround this issue with downloading only the filtered dataset. I also tried setting the donload size to 10 mb with shiny.maxRequestSize=30*1024^2
I really need the option to save the whole dataset. If anyone could provide some insights I would much appreciate it (And yes, I run the App in the Browser)
my ui function looks like this:
tbl <- read.csv(file.choose(new = FALSE), header = TRUE, sep = ",", row.names=1)
ui <- navbarPage(
title = "Data Table Options",
#Tab with the dataset table
tabPanel("Lot Dataset",
div(h3("Download"), style = "color:blue"),
helpText(" Select the download format"),
radioButtons("type", "Format type:",
choices = c("Excel (CSV)", "Text (Space Separated)", "Doc")),
helpText(" Click on the download button to download the Lot Dataset"),
downloadButton("download_filtered", "Download Filtered Data"),
br(),
br(),
br(),
DT::dataTableOutput("dt"), #datatable
),
)
my server function like this:
server <- function(session, input, output) {
#Increasing Downloadsize to 10MB
options(shiny.maxRequestSize=10*1024^2)
#render the datatable
output$dt <- DT::renderDataTable({
datatable(tbl, filter = "top", options = list(
lengthMenu = list(c(25, 50, 100, -1), c("25", "50", "100", "All")),
pageLength = 25))
})
#bottom panel with row indices
output$filtered_row <-
renderPrint({
input[["dt_rows_all"]]
})
#file extension for download
fileext <- reactive({
switch(input$type,
"Excel (CSV)" = "csv", "Text" = "txt", "Doc" = "doc")
})
#downloadHandler() for file download of Lot Dataset
output$download_filtered <- downloadHandler(
filename = function() {
paste("MLdataset_test", fileext(), sep=".") #filename
},
content = function(file) {
#write tbl with filter
write.csv(tbl[input[["dt_rows_all"]], ],
file = file, row.names = F)
}
)
}
Any help appreciated!!!
I am getting error file, while downloading data of bar chart rendered in shiny UI.
There is a download button just below the chart. While click on the 'Download data' button, data should be downloaded into csv format.
Code:
library(shiny)
library(ECharts2Shiny)
dat <- data.frame(c(1, 2, 3), c(2, 4, 6))
names(dat) <- c("Type-A", "Type-B")
row.names(dat) <- c("Time-1", "Time-2", "Time-3")
ui <- fluidpage( loadEChartsLibrary(),
tags$div(id="test", style="width:50%;height:400px;"),
deliverChart(div_id = "test"), downloadButton("test", "Download Data"))
server <- function(input, output) {
renderBarChart(div_id = "test", grid_left = '1%', direction = "vertical",
data = dat)
}
shinyApp(ui = ui, server = server)
I want to download the data of that bar chart in ".csv" format.
Can anyone help me out to correct the code?
Thank you.
I think you cannot use the same "renderTable" server output for all of your UI inputs. AKA, you need to make a separate input and output for your image in the form of a downloadable file. Here is an example of what I did to download a .csv file:
output$downloadData <- reactive({
output$downloadData <- downloadHandler(
filename = function() {
paste("ProcessedData-", Sys.Date(), ".csv", sep="")
},
content = function(file) {
write.csv(DataTable, file)
}
)
Therefore in your download button you would replace "test" with "downloadData" so that it connects to a new server output. Notice that I am creating the file here with write.csv, but not actually writing to any disk just generating the file and passing it into the downloadData output for users to trigger and then save to their own disk when they hit the downloadData input button. You are trying to save a picture so I suggest trying something along the lines of generating an image file inside of the content call. Recall that you can save images as objects:
#up in the UI somewhere
ui <- fluidpage(loadEChartsLibrary(),
tags$div(id="test", style="width:50%;height:400px;"),
deliverChart(div_id = "test"), downloadButton("downloadData", "Download Data"))
server <- function(input, output) {
output$test <- renderBarChart(div_id = "test", grid_left = '1%', direction = "vertical",
data = dat)
output$downloadData <- reactive({
output$downloadData <- downloadHandler(
filename = function() {
paste("Image.png", sep="") #just the file name you want to have as default
},
content = function(file) {
write.csv(DataTable, file)
)
}
I don't have your actual code so this may not work as a plug and play solution, but I believe this is the right direction.
I have created an R shiny application to download dynamic reports using R Markdown. Previously I was downloading one report at a time by selecting the row in the data table in r shiny and clicking on download button, the selected row's column values would get filled in the report, this was working perfectly fine.
But now i am trying to download multiple reports, so that if I select multiple rows in a datatable in r shiny and click on download, the number of reports downloaded should be equal to number of rows selected.
For this I am trying to create a zip file which contains all my individual report but I am getting this
error: pandoc document conversion failed with error 1
I had researched for this error but couldn't find anything. Please help!
ui <- {
tagList(
div(id = "downloadBtn",
downloadButton("downloadData", "Download")),
DT::dataTableOutput('myTable1')
)
}
dataJ <- read.csv(file = "iris.csv", header = TRUE, stringsAsFactors =
FALSE)
server <- function(input, output)
{
output$myTable1 <- DT::renderDataTable({
DT::datatable(dataJ, options = list(orderClasses = TRUE), filter = 'top')})
output$downloadData <- downloadHandler(
filename = function()
{
paste("output", "zip", sep = ".")
},
content = function(file)
{
k = list(input$myTable1_rows_selected)
fs <- c()
for ( i in k)
{
params <- list(j=i)
path <- paste(i,".docx")
rmarkdown::render("R_markdown_script.Rmd", rmarkdown::word_document(),
output_file = path , params = params,
envir = new.env(parent = globalenv()))
fs <- c(fs,path)
}
zip(zipfile = file, files = fs)
if (file.exists(paste0(file, ".zip")))
file.rename(paste0(file, ".zip"), file)
},
contentType = "application/zip" )
}
runApp(list(ui = ui, server = server))
Here is a reproducible example (to make it work, create an rmarkdown file with the default content using RStudio, and save it as "test.rmd" in the same folder as your Shiny app).
Important:
You need to run the app externally inside your web browser. Somehow it does not work in the viewer pane or RStudio window (you get the download window but then no file is saved).
If you are on Windows, you need to make sure that you install RTools first, and also put the rtools/bin folder in your system path.
app.R
library(shiny)
ui <- shinyUI(fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
downloadButton("downloadData", "Download")
),
mainPanel(
DT::dataTableOutput('myTable1')
)
)
))
server <- shinyServer(function(input, output) {
output$myTable1 <- DT::renderDataTable(iris)
output$downloadData <- downloadHandler(
filename = function() {
paste0("output", ".zip")
},
content = function(file) {
k <- input$myTable1_rows_selected
fs <- c()
for (i in k) {
path <- paste0(i, ".docx")
rmarkdown::render("test.rmd", rmarkdown::word_document(), output_file = path)
fs <- c(fs, path)
}
zip(file, fs)
},
contentType = "application/zip"
)
})
shinyApp(ui = ui, server = server)
Hello I also installed Rtools/bin and was running the code on the web browser, but when I click on download button, download window doesn't comes up and shows '404 Not Found', but when I check the directory, the doc files report are saving directly to directory, no zip file is produced. Please see below code.
ui <- {
tagList(
div(id = "downloadBtn",
downloadButton("downloadData", "Download")),
DT::dataTableOutput('myTable1')
)
}
dataJ <- read.csv(file = "iris.csv", header = TRUE, stringsAsFactors =
FALSE)
server <- function(input, output)
{
output$myTable1 <- DT::renderDataTable({
DT::datatable(dataJ, options = list(orderClasses = TRUE), filter = 'top')})
output$downloadData <- downloadHandler(
filename = ("output.zip"),
content = function(file)
{
k <- (input$myTable1_rows_selected)
fs <- c()
for ( i in k)
{
path <- paste0(i,".docx")
rmarkdown::render("R_markdown_script.Rmd", output_file = path ,
params = list(j=i), envir = new.env(parent = globalenv()))
fs <- c(fs,file)
}
zip(zipfile = file, files = fs)
},
contentType = "application/zip" )
}
runApp(list(ui = ui, server = server))`
I have part of a shiny function where the user selects the download image type (.png, .tiff etc) and clicks a button to download it. But all options download in .png format and I can't seem to find out what is wrong.
Note that the preview is always png. The download function creates different file types upon clicking the button. Another point to note is the use of file.copy() in downloadhandler rather than something like
png(name)
plot()
dev.off()
This is because my plotting function is complex and file.copy() is more practical.
The code is below.
#ui.R ----------------------------------------------------------
shinyUI(fluidPage(
titlePanel("Download test"),
sidebarLayout(
sidebarPanel(
numericInput("fheight", "Height (cm)", min=2, max=15, step=1, value = 10),
numericInput("fwidth", "Width (cm)", min=2, max=15, step=1, value = 10),
selectInput("fres", "Res", choices=c("100","200","300"), selected = "100"),
selectInput("fformat", "File type", choices=c("png","tiff","jpeg","pdf"), selected = "png", multiple = FALSE, selectize = TRUE),
downloadButton('bn_download', 'Download Plot')
),
# Show a plot of the generated distribution
mainPanel(
imageOutput("plotoutput")
)
)
))
# server.R ----------------------------------------------------------
shinyServer(function(input, output) {
# store some values
store <- reactiveValues(dname="AwesomeDownload")
# data creation
fn_data <- reactive({
df <- data.frame(x=rnorm(50),y=rnorm(50))
})
# create filename
fn_downloadname <- reactive({
if(input$fformat=="png") filename <- paste0(store$dname,".png",sep="")
if(input$fformat=="tiff") filename <- paste0(store$dname,".tif",sep="")
if(input$fformat=="jpeg") filename <- paste0(store$dname,".jpg",sep="")
if(input$fformat=="pdf") filename <- paste0(store$dname,".pdf",sep="")
return(filename)
})
# render png preview
output$plotoutput <- renderImage({
df <- fn_data()
fheight <- input$fheight
fwidth <- input$fwidth
fres <- as.numeric(input$fres)
png(paste0(store$dname,".png",sep=""), height=fheight, width=fwidth, res=fres, units="cm")
plot(df)
dev.off()
return(list(src = paste0(store$dname,".png",sep=""),
contentType = "image/png",
width = round((input$fwidth*as.numeric(input$fres))/2.54, 0),
height = round((input$fheight*as.numeric(input$fres))/2.54, 0),
alt = "plot"))
},deleteFile=TRUE)
# download function
fn_download <- function()
{
df <- fn_data()
fheight <- input$fheight
fwidth <- input$fwidth
fres <- as.numeric(input$fres)
if(input$fformat=="pdf") fheight <- round(fheight*0.3937,2)
if(input$fformat=="pdf") fwidth <- round(fwidth*0.3937,2)
if(input$fformat=="png") png(fn_downloadname(), height=fheight, width=fwidth, res=fres, units="cm")
if(input$fformat=="tiff") tiff(fn_downloadname(), height=fheight, width=fwidth, res=fres, units="cm",compression="lzw")
if(input$fformat=="jpeg") jpeg(fn_downloadname(), height=fheight, width=fwidth, res=fres, units="cm",quality=100)
if(input$fformat=="pdf") pdf(fn_downloadname(), height=fheight, width=fwidth)
plot(df)
dev.off()
}
# download handler
output$bn_download <- downloadHandler(
filename = fn_downloadname(),
content = function(file) {
fn_download()
file.copy(fn_downloadname(), file, overwrite=T)
}
)
})
Removing parenthesis in the download filename fixed the issue. Yeah, don't even ask. I have no idea why this is so either. But it works.
Joe Cheng's answer:
Change this line:
filename = fn_downloadname(),
to this:
filename = fn_downloadname,