将R Shiny Page导出为PDF [英] Export R Shiny Page to PDF

查看:119
本文介绍了将R Shiny Page导出为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.

  1. 由于您使用的是ggplot2,而ggplot2grid地块的王者,因此我认为保存图/表的一个简单选择是使用gridExtra包.使用grid.arrangearrangeGrobs您可以将grobs保存到预定义的设备.然后,downloadhandler将进行下载.

  1. Since you are using ggplot2 which is king of grid plots, I think one easy option to save plots/tables is to use gridExtra package. Using grid.arrange or arrangeGrobs 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆