将R Shiny Page导出为PDF [英] Export R Shiny Page to PDF
问题描述
我有一个大型的Shiny应用程序,其中包含许多提示,然后根据这些输入生成表格和绘图.我不使用rmarkdown或knitr或其他任何格式来格式化输出.我只使用标准的Shiny元素(sidebarPanel,mainPanel等).对于图和表,我使用标准的反应性renderPlot和renderTable对象. 我正在寻找一种简单的方法来创建一个名为导出为PDF"的按钮,该按钮可将页面上的元素导出为PDF文档.
I have a large Shiny application that has a number of prompts, then generates tables and plot based on those inputs. I don't use rmarkdown or knitr or anything to format the output. I just use the standard Shiny elements (sidebarPanel, mainPanel, etc.). For the plots and tables I use the standard reactive renderPlot and renderTable objects. I'm looking for an easy way to have a button called "Export to PDF" that exports the elements on the page to a PDF document.
我已经研究过使用knitr和rmarkdown生成具有某种精美格式的文档(请参见此处和此处为例). 问题在于,似乎需要重新生成Rmd文件或downloadHandler对象中的server.R内的表和图,而我想避免这种情况.
I've looked into using knitr and rmarkdown to generate a document with some fancy formatting (see here and here for examples). The problem is that it appears that I'll need to regenerate the tables and plots either within the Rmd file or the server.R within a downloadHandler object, and I'd like to avoid that.
有什么方法可以更轻松地将页面输出为pdf.更具体地说,是否有任何方法可以直接从Rmd文件中引用输出表和图(即output $对象),所以不需要两次生成图和表.
Is there any way to output the page as a pdf more easily. More specifically, is there any way to directly reference the output tables and plots (i.e. the output$ objects) from within the Rmd file so that plots and tables don't need to be generated twice.
这是一些简化的代码.注意getDataset()是一个反应性函数,可根据输入查询数据库. 我的目标是简单地添加一个导出"按钮,以导出已经生成的绘图和表格. (此外,还有什么方法可以获取在所有反应性元素之间共享的反应性数据集?即不需要在每个对象中都具有ds<-getDataset()吗?)
Here is some simplified code. Note getDataset() is a reactive function that queries a database based on the inputs. My goal is to simply add an "Export" button that exports the already-generated plots and table. (Also as a side note, is there any way I can get a reactive dataset that is shared among all reactive elements? i.e. not need to have ds <- getDataset() in every object?)
服务器
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
})
UI
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"))
)
)
)
)
推荐答案
首先,您应该真正产生一个可重现的示例,而不仅仅是代码示例.我们应该复制并粘贴您的代码,它将运行.
First of all , you should really produce a reproducible example not just a sample of your code. We should copy and paste your code and it will run.
-
由于您使用的是
ggplot2
,而ggplot2
是grid
地块的王者,因此我认为保存图/表的一个简单选择是使用gridExtra
包.使用grid.arrange
或arrangeGrobs
您可以将grobs保存到预定义的设备.然后,downloadhandler将进行下载.
Since you are using
ggplot2
which is king ofgrid
plots, I think one easy option to save plots/tables is to usegridExtra
package. Usinggrid.arrange
orarrangeGrobs
you can save your grobs to predefined device. Then, downloadhandler will do the download.
为了不每次都重新生成所有图,我认为一种解决方案是将它们保存在每次更改图时都会更新的全局变量中.在这里reactiveValues
可以帮助您存储绘图和表格以及动态变量.
To not regenerate all the plots each time, I think one solution is to save them in a global variable that you update each time you change the plot. Here reactiveValues
come in rescue to store plots and tables ad dynamic variable.
解决方案
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()
}
)
})
这篇关于将R Shiny Page导出为PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!