Export R Shiny PDF

I have a large Shiny application that contains several queries and then generates tables and graphs based on these inputs. I do not use rmarkdown or knitr or anything to format the output. I just use standard Shiny elements (sidebarPanel, mainPanel, etc.). For graphs and tables, I use the standard react objects renderPlot and renderTable. I'm looking for an easy way to have an β€œExport to PDF” button that exports elements on a page to a PDF document.

I learned how to use knitr and rmarkdown to create a document with some fancy formatting (see here and here for an example). The problem is that it seems to me that I will need to restore the tables and graphs in the Rmd file or on the .R server in the downloadHandler object, and I would like to avoid this.

Is it possible to easily display the page as a PDF. More specifically, is there a way to directly reference output tables and graphs (i.e., Output $ objects) from an Rmd file so that graphs and tables do not need to be generated twice.

Edit: Here are some simplified codes. Note getDataset () is a reactive function that queries a database based on input. My goal is to simply add the Export button, which exports the already created graphs and table. (Also, as a note, is there any way to get a reactive dataset that is shared between all reactive elements, i.e. Don't need to have ds <- getDataset () in each object?)

Server

output$hist <- renderPlot({ ds <- getDataset() # do data transformations ggplot(ds, aes(val)) + geom_histogram(binwidth = binSize, aes(fill = ..count..)) + labs(title = "val dist", x = "val", y = "Count") + scale_fill_gradient("Count", low = "green", high = "red", guide = FALSE) + scale_x_continuous(limits = c(min(ds$val), quantile(ds$val, 0.99))) + geom_hline(yintercept=maxY, linetype=3) }) output$time <- renderPlot({ ds <- getDataset() # do data transformations ggplot(ds, aes(as.POSIXlt(unixTime, origin="1970-01-01", tz="UTC"), val), colour = val) + scale_y_continuous(limits = c(min(ds$val), quantile(ds$val, 0.99))) + labs(title = "Val Over Time", x = "Time (UTC)", y = "val (ms)") + geom_point(alpha = 0.3, size = 0.7) + geom_smooth() }) output$stats <- renderTable({ statsDf = getDataset() # do data transformations statsDf }) 

interface

 ui <- fluidPage( titlePanel("Results"), sidebarLayout( sidebarPanel( dateInput("startDateTime", "Start Date:", value = "2016-10-21"), textInput("startTime", "Start Time", "00:00:00"), br(), dateInput("endDateTime", "End Date:", value = "2016-10-21"), textInput("endTime", "End Time", value = "02:00:00"), br(), submitButton("Submit") ), mainPanel( tabsetPanel(type = "tabs", tabPanel("Plots", plotOutput("hist"), plotOutput("time"), tabPanel("Statistics", tableOutput("stats")) ) ) ) ) 
+6
source share
1 answer

First of all, you should really reproduce a reproducible example, not just a sample of your code. We need to copy and paste your code and it will run.

Idea

  • Since you are using ggplot2 , which is the king of grid graphs, I think one easy way to save graphs / tables is to use the gridExtra package. Using grid.arrange or arrangeGrobs , you can save your grobs to a predefined device. Then the loading arm will boot.

  • In order not to regenerate all the graphs every time, I think that one of the solutions is to save them in a global variable that you update every time you change the graph. Here reactiveValues come to the rescue for storing graphs and tables ad dynamic variable.

Decision

ui.R

 library(shiny) shinyUI(fluidPage( # Application title titlePanel("Save ggplot plot/table without regenration"), # Sidebar with a slider input for number of bins sidebarLayout( sidebarPanel( downloadButton('export') ), # Show a plot of the generated distribution mainPanel( plotOutput("p1"), plotOutput("p2"), tableOutput("t1") ) ) )) 

server.R

 library(shiny) library(ggplot2) library(gridExtra) shinyServer(function(input, output) { ## vals will contain all plot and table grobs vals <- reactiveValues(p1=NULL,p2=NULL,t1=NULL) ## Note that we store the plot grob before returning it output$p1 <- renderPlot({ vals$p1 <- qplot(speed, dist, data = cars) vals$p1 }) output$p2 <- renderPlot({ vals$p2 <- qplot(mpg, wt, data = mtcars, colour = cyl) vals$p2 }) ## same thing for th etable grob output$t1 <- renderTable({ dx <- head(mtcars) vals$t1 <- tableGrob(dx) dx }) ## clicking on the export button will generate a pdf file ## containing all grobs output$export = downloadHandler( filename = function() {"plots.pdf"}, content = function(file) { pdf(file, onefile = TRUE) grid.arrange(vals$p1,vals$p2,vals$t1) dev.off() } ) }) 
+2
source

Source: https://habr.com/ru/post/1011734/


All Articles