Download the generated table in a csv format - R shiny - r

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

Download filtered tableOutput in Shiny

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)

Download multiple dataframes in multiple sheets of the same excel file in a shiny app

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)

Export user input and table out put to one Excel file with Shiny

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.

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