Witness
Witness

Reputation: 15

Downloading from Shiny

Im using the following code on shiny. I want to be able to download the table and the plot

Create data set from clicks in Shiny ggplot

The code itself works fine but in having trouble figuring out how to download the table and the plot.

library(shiny)
library(ggplot2)

ui <- pageWithSidebar(
    headerPanel("Example"),
    sidebarPanel(
        radioButtons("color", "Pick Color", c("Pink", "Green", "Blue")),
        selectInput("shape", "Select Shape:", c("Circle", "Triangle"))
    ),
    mainPanel(
        fluidRow(column(width = 6,
                        h4("Click plot to add points"),
                        actionButton("rem_point", "Remove Last Point"),
                        plotOutput("plot1", click = "plot_click")),
                 column(width = 6,
                        h4("Table of points on plot"),
                        tableOutput("table")))
    )
)

server = function(input, output){

    ## 1. set up reactive dataframe ##
    values <- reactiveValues()
    values$DT <- data.frame(x = numeric(),
                            y = numeric(),
                            color = factor(),
                            shape = factor())

    ## 2. Create a plot ##
    output$plot1 = renderPlot({
       ggplot(values$DT, aes(x = x, y = y)) +
            geom_point(aes(color = color,
                           shape = shape), size = 5) +
            lims(x = c(0, 100), y = c(0, 100)) +
            theme(legend.position = "bottom") +
            # include so that colors don't change as more color/shape chosen
            scale_color_discrete(drop = FALSE) +
            scale_shape_discrete(drop = FALSE)
    })

    ## 3. add new row to reactive dataframe upon clicking plot ##
    observeEvent(input$plot_click, {
        # each input is a factor so levels are consistent for plotting characteristics
        add_row <- data.frame(x = input$plot_click$x,
                              y = input$plot_click$y,
                              color = factor(input$color, levels = c("Pink", "Green", "Blue")),
                              shape = factor(input$shape, levels = c("Circle", "Triangle")))
        # add row to the data.frame
        values$DT <- rbind(values$DT, add_row)
    })

    ## 4. remove row on actionButton click ##
    observeEvent(input$rem_point, {
        rem_row <- values$DT[-nrow(values$DT), ]
        values$DT <- rem_row
    })

    ## 5. render a table of the growing dataframe ##
    output$table <- renderTable({
        values$DT
    })
}

shinyApp(ui, server)

The values$DT in the rendertable etc is the sticking point as I've no datasetInput() that are in the shiny examples. The problem is that the table and plot are dynamical and need to be changed similar to this

Download table generated independetly in renderTable output in R shiny

I can't figure out how to change it.

Upvotes: 1

Views: 315

Answers (1)

phalteman
phalteman

Reputation: 3542

Downloading user generated material (plots and tables) requires the combined use of downloadButton and downloadHandler. See here for help on understanding downloading.

For your case, the first step is to include downloadButtons in the UI.

ui <- pageWithSidebar(
  headerPanel("Example"),
  sidebarPanel(
    radioButtons("color", "Pick Color", c("Pink", "Green", "Blue")),
    selectInput("shape", "Select Shape:", c("Circle", "Triangle")),
    downloadButton("dlPlot", "Download Current Plot"),
    downloadButton("dlTab", "Download Current Table")
  ),
  mainPanel(
    fluidRow(column(width = 6,
                    h4("Click plot to add points"),
                    actionButton("rem_point", "Remove Last Point"),
                    plotOutput("plot1", click = "plot_click")),
             column(width = 6,
                    h4("Table of points on plot"),
                    tableOutput("table")))
  )
)

Next, is including downloadHandlers in the server. I put this chunk at the end of your server call with no other changes:

  output$dlPlot <- downloadHandler(
    filename="Plot_Download.jpg",
    content=function(file){
      ggsave(file, device = "jpeg")
    }
  )

  output$dlTab <- downloadHandler(
    filename="Table_Download.csv",
    content=function(file){
      write.csv(x=values$DT, file=file)
    }
  )

I find ggsave() and write.csv() to be the easiest operations to use with downloadHandler, but there are other ways as well, which you can find in other SO questions.

Upvotes: 3

Related Questions