My app allows the user to generate some plots and save them as png.
I want the app as well to update a csv file based on some inputs made into the app by the user.
For example purposes, I created a toy app that generates a csv file in a given folder.
In both cases, the app doesn't display any error message or info, but it doesn't store any file anywhere.
library(shiny)
library(ggplot2)
library(AlphaPart)
ui <- fluidPage(
selectInput("var1","Select var1", choices = names(iris)),
selectInput("var2","Select var2", choices = names(iris)),
plotOutput("myplot"),
downloadLink("downloadPlot", label = icon("download")))
server <- function(input, output, session) {
data <- reactive(iris)
var1 <- reactive({input$var1})
var2 <- reactive({input$var2})
# Genearte plot
draw_boxplot <- function(data, var1, var2){
ggplot(data=data(), aes(x=.data[[input$var1]], y = .data[[input$var2]]))
geom_boxplot()
}
plot1 <- reactive({
req(data(), input$var1, input$var2)
draw_boxplot(data(), var1(), var2())
})
output$myplot <- renderPlot({
plot1()
})
#Download
output$downloadPlot <- downloadHandler(
filename = function() {
return("Plot.png")
},
content = function(file) {
png(file)
print(plot1())
dev.off()
})
#Write csv
eventReactive(input$downloadPlot, {
dat <- as.data.frame(c(input$num_var_1, input$num_var_2))
write.csv(dat, "C:/dat.csv", row.names = FALSE)
})
}
shinyApp(ui, server)
CodePudding user response:
library(shiny)
library(ggplot2)
library(AlphaPart)
library(spsComps)
ui <- fluidPage(
selectInput("var1","Select var1", choices = names(iris)),
selectInput("var2","Select var2", choices = names(iris)),
plotOutput("myplot"),
downloadLink("downloadPlot", label = icon("download")))
server <- function(input, output, session) {
data <- reactive(iris)
var1 <- reactive({input$var1})
var2 <- reactive({input$var2})
# Genearte plot
draw_boxplot <- function(data, var1, var2){
ggplot(data=data(), aes(x=.data[[input$var1]], y = .data[[input$var2]]))
geom_boxplot()
}
plot1 <- reactive({
req(data(), input$var1, input$var2)
draw_boxplot(data(), var1(), var2())
})
output$myplot <- renderPlot({
plot1()
})
#Download
downloaded <- reactiveVal(0)
output$downloadPlot <- downloadHandler(
filename = function() {
return("Plot.png")
},
content = function(file) {
png(file)
print(plot1())
dev.off()
on.exit({spsComps::incRv(downloaded)})
})
#Write csv
observeEvent(downloaded(), {
dat <- as.data.frame(c(input$num_var_1, input$num_var_2))
utils::write.csv(dat, "dat.csv", row.names = FALSE)
print("File saved")
}, ignoreInit = TRUE)
}
shinyApp(ui, server)
- Unfortunately, you can't observe download event. So here we do, introduce another
reactiveValwhich we can change inside the download event so we will know if the download button has been clicked. spsComps::incRvis a short hand function fordownloaded(isolate(downloaded()) 1), so it increase thereactiveValevery time by one.- use
on.exiton the end to make sure this happens only when the plot is successful. - Instead of using
eventReactive,observeEventshould be used since you are not returning any value but just write a file.
