My shiny app generates a table that I want to make available for download in a csv format.
ui = fluidPage( ...
tableOutput("contents"),
downloadButton("download", "Download results in csv format")
)
server <- function( input, output, session ) {
output$contents <- renderTable( ... )
output$download <- downloadHandler(
filename = function() {
paste(contents, ".csv", sep = "")
},
content = function(file) {
write.csv(contents(), file, row.names = FALSE)
}
)
I understand that I have to create a reactive object, but the renderTable itself uses another reactive object (uploaded dataset), so it looks like I need to nest one reactive object into another, and it does not seem to work. Will appreciate any help. Thank you!
EDIT: Added an example using renderTable instead of renderDataTable, as requested by the question and in the comment section:
Here is an example using the iris dataset. I also added a table from the DT package. You should not paste the data in the filename function, only in the in the write.csv function.
```{r}
library(shinydashboard)
library(dplyr)
library(DT)
```
setosa <- filter(iris, Species == "setosa")
ui = fluidPage(
downloadButton("download", "Download results in csv format") ,
column(12,
DT::dataTableOutput ("content"),
style = " overflow-y: scroll;overflow-x: scroll;")
)
server <- function(input, output, session) {
output$content <-
renderDataTable(head(setosa))
output$download <-
downloadHandler(
filename = function () {
paste("MyData.csv", sep = "")
},
content = function(file) {
write.csv(content, file)
}
)
}
shinyApp(ui, server)
```
Using renderTable instead of renderDataTable
library(shiny)
library(dplyr)
library(DT)
setosa <- filter(iris, Species == "setosa")
ui = fluidPage(
downloadButton("download", "Download results in csv format"),
tableOutput("table")
)
server <- function(input, output, session) {
data <- data.frame(setosa)
output$table <-
renderTable(data)
output$download <-
downloadHandler(
filename = function () {
paste("MyData.csv", sep = "")
},
content = function(file) {
write.csv(data, file)
}
)
}
shinyApp(ui, server)
Related
I have the following data:
> data
products id
1 P1 280386
2 P1 285184
3 P2 293154
4 P1 294245
I have built a simple shiny code. I first filter the table and then I want to download the filtered table. I write the following
library(shiny)
library(shinyWidgets)
library(tidyverse)
library(DT)
data <- read.csv("Desktop/data.csv")
products <- unique(data$products)
ui <- fluidPage(
fluidRow(
column(4,
selectInput("product", "Product", products,
multiple = TRUE),
downloadButton("download", "Download")),
column(8,
tableOutput("errorTable")
)
)
)
server <- function(input, output, session) {
output$errorTable <- renderTable({
subset(data, products == input$product)
}
)
output$download <- downloadHandler(
filename = function() {
paste("data-",Sys.Date(), ".csv", sep = "")
},
content = function(file) {
write.csv(data, file)
}
)
}
shinyApp(ui, server)
However, this code only downloads the full table, not the filtered one. I have searched some question but none explained this case specifically. thanks in advance
Try this
library(shiny)
library(shinyWidgets)
library(tidyverse)
library(DT)
data <- read.csv("Desktop/data.csv")
products <- unique(data$products)
ui <- fluidPage(
fluidRow(
column(4,
selectInput("product", "Product", products,
multiple = TRUE),
downloadButton("download", "Download")),
column(8,
tableOutput("errorTable")
)
)
)
server <- function(input, output, session) {
#you need to create a reactive object with a NULL starting value
listofitems <- reactiveValues(data = NULL )
#observe the changes in input$product and update the reactive object
observeEvent( input$product, {
print("Hello: observeEvent for input$product is triggered")
#debug using browser()
listofitems$data <- subset(data, products == input$product)
showNotification("Products updated",
type = "message",
duration = 4,
closeButton = TRUE)
}, ignoreInit = T,ignoreNULL = TRUE)
output$errorTable <- renderTable({
listofitems$data
}
)
output$download <- downloadHandler(
filename = function() {
paste("data-",Sys.Date(), ".csv", sep = "")
},
content = function(file) {
write.csv(listofitems$data, file)
}
)
}
shinyApp(ui, server)
I wonderif there is a way to download 2 dataframes in the same excel file but in different sheet via shiny app.
library(shiny)
library(xlsx)
ui <- shinyUI(fluidPage(
titlePanel("Testing File upload"),
sidebarLayout(
sidebarPanel(
downloadButton("dl","Export in Excel")
),
mainPanel(
)
)
))
server <- shinyServer(function(input, output) {
output$dl <- downloadHandler(
filename = function() {
paste0("df_dmodel", "_Table", ".xls")
},
content = function(file){
tbl<-iris
tbl2<-mtcars
write.xlsx(tbl,tbl2 file,
sheetName = "Sheet1", row.names = FALSE)
}
)
})
shinyApp(ui = ui, server = server)
try changing your server code to this. Also, remember to open the app in your browser and not just the rstudio viewer (assuming your are using rstudio). Hope this helps!
server <- shinyServer(function(input, output) {
output$dl <- downloadHandler(
filename = function() {
paste0("df_dmodel", "_Table", ".xlsx")
},
content = function(file){
tbl<-iris
tbl2<-mtcars
sheets <- mget(ls(pattern = "tbl")) # getting all objects in your environment with tbl in the name
names(sheets) <- paste0("sheet", seq_len(length(sheets))) # changing the names in your list
writexl::write_xlsx(sheets, path = file) # saving the file
}
)
})
An alternative to Andrew's answer using write.xlsx from openxlsx with a list of dataframes.
library(shiny)
library(openxlsx)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
downloadButton("dl","Export in Excel")
),
mainPanel(
)
)
))
server <- shinyServer(function(input, output) {
output$dl <- downloadHandler(
filename = function() {
"test.xlsx"
},
content = function(filename){
df_list <- list(iris=iris, mtcars=mtcars)
write.xlsx(x = df_list , file = filename, row.names = FALSE)
}
)
})
shinyApp(ui = ui, server = server)
I have written an app allowing users to provide some inputs. The app will call a function to do some calculations and generate an output in table format.
I would like to add a button that allows users to download both the inputs and outputs into an Excel spreadsheet (with two tabs)
Below is a simplified version of the code where I want to download the inputs and the example table. I have tried the following code but failed:
library(shiny)
library(openxlsx)
somefunction <- function() {
data.frame(text = c("sample1","sample2"))}
server <- function(input, output, session) {
dataReactive <- reactive({
data.frame(text = c(input$text1, input$text2, input$text3))
})
observeEvent(input$goButton,{
output$exampleTable <- DT::renderDataTable({somefunction()})
})
output$downloadExcelSheet <- downloadHandler(
filename = function() {
paste("result",Sys.Date(), ".xlsx",sep="")
},
content = function(file) {
write.xlsx(list(dataReactive(),exampleTable), file)
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
textInput("text1","Text 1:",value="Input 1"),
textInput("text2","Text 2:",value="Input 2"),
actionButton("goButton", "Calculate"),
downloadButton("downloadExcelSheet", "Download Data")
),
mainPanel(
DT::dataTableOutput("exampleTable")
)
)
)
shinyApp(ui = ui, server = server)
server <- function(input, output, session) {
dataReactive <- reactive({
data.frame(text = c(input$text1, input$text2, input$text3))
})
data <- reactiveValues()
observeEvent(input$goButton,{
output$exampleTable <- DT::renderDataTable({
data$df <- somefunction()
})
})
output$downloadExcelSheet <- downloadHandler(
filename = function() {
paste("result",Sys.Date(), ".xlsx",sep="")
},
content = function(file) {
write.xlsx(list(dataReactive(),data$df), file)
})
}
It's better to move data$df <- somefunction() to observeEvent and move DT::renderDataTable outside observeEvent like so
observeEvent(input$goButton,{
data$df <- somefunction()
})
output$exampleTable <- DT::renderDataTable({data$df})
Use reactiveValues as an intermediate state to save variables and in order to reuse them later.
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"
)
})
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.