在 Shiny 中下载 PDF 报告 [英] Download Pdf report in Shiny

查看:77
本文介绍了在 Shiny 中下载 PDF 报告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个闪亮的应用程序,它将创建 2 个地块和一个表格.

Im making a shiny app, that will create 2 plots and one table.

选择输入部分有很多选项.

There are a lot of options in the select input part.

一旦选择,它将对 data.frame 进行子集化并返回另一个要分析的 data.frame.

Once selected it will subset the data.frame and return with another data.frame to be analised.

它会相应地进行绘图,我希望它以 pdf(或 html)格式生成包含输入详细信息的报告.

It will plot accordingly and I want it to generate a report in pdf (or html) with the details of the input.

喜欢生成报告"按钮,并为我提供该特定输入的绘图以及 input$company.pdf(或 html)名称.

Like "Generate Report" button and give me the plot for that specific input and with the input$company.pdf (or html) name.

我到处搜索,但我找不到如何做到这一点.

I have searched everywhere and I cant find out how to do this.

我还想将 .Rmd 编​​辑为更好的格式.只有一些短语介绍等.

I also want to edit the .Rmd to be in a nicer format. With just some phrases for introduction and so on.

这是我的详细信息.

所有代码

library(ggplot2)
library(prophet)
library(markdown)
library(knitr)
order <- read.csv("order.csv" , header = T, sep = ",", stringsAsFactors = F)

order$Date <- strftime(order$Date.added, format = "%Y-%m-%d")
order$Date <- as.Date(order$Date)
order$Payment.company <- as.character(order$Payment.company)

choices <- sort(unique(as.character(order$Payment.company)))





ui <- shinyUI(fluidPage(

        headerPanel("Company Order Analytics"),

        sidebarPanel(position = "left",
                     selectInput("company", "Select Company:", 
                                 choices = choices, selected = "A&E Scientific sprl", multiple = FALSE),
                     submitButton("Run"),

                     downloadButton("report", "Generate report"),


                     mainPanel(position="right",
                               tabsetPanel(
                                       tabPanel("Plot",  plotOutput("plot")),
                                       tabPanel("Table", tableOutput("table")),
                                       tabPanel("Graphic",  plotOutput("plot1"))
                               )))))

server <- shinyServer(function(input, output, session) {

        plot1 <- reactive({

                a <- subset(order, order$Payment.company == input$company)
                a$l <- log10(a$Total)
                m <- subset(a, select=c("Total", "Date"))
                colnames(m) <- c("y", "ds")
                z <- prophet(m)
                future <- make_future_dataframe(z, periods = 365)
                forecast <- predict(z, future)
                plot(z, forecast, xlab = "Date", ylab = "Value Order GBP")



        })
        plot2 <- reactive({
                a <- subset(order, order$Payment.company == input$company)
                a$l <- log10(a$Total)
                m <- subset(a, select=c("Total", "Date"))
                colnames(m) <- c("y", "ds")
                z <- prophet(m, yearly.seasonality = TRUE)
                future <- make_future_dataframe(z, periods = 365)
                forecast <- predict(z, future)
                prophet_plot_components(z, forecast)


        })

        table1 <- reactive({

                a <- subset(order, order$Payment.company == input$company)
                n <- nrow(a)
                ma <- max(a$Total)
                x  <- median(a$Total)
                t <- sum(a$Total)

                tbl1 <- data.frame("Orders"= n, "Max"=ma, "Median"=x, "Total"=t)
                return(tbl1)

        }
        )

        output$plot <- renderPlot(plot1(),width = 850, height = 425)
        output$plot1 <- renderPlot(plot2(),width = 850, height = 425)
        output$table <- renderTable(table1())

        output$report <- downloadHandler(
                # For PDF output, change this to "report.pdf"
                filename = "report.html",
                content = function(file) {
                        before processing it, in
                        .
                        tempReport <- file.path(tempdir(), "report.Rmd")
                        file.copy("report.Rmd", tempReport, overwrite = TRUE)




                        rmarkdown::render(tempReport, output_file = file,
                                          params = params,
                                          envir = new.env(parent = globalenv())
                        )
                }
        )


                })

名为 report_file.Rmd 的 R 降价

R markdown named report_file.Rmd

---
title: "Parameterized Report for Shiny"
output: pdf_document
params:
  table: 'NULL'
  plot: 'NULL'
---

```{r}
params[["plot"]]
```

```{r}
params[["plot1"]]
```

```{r}
params[["table"]]
```

UI 和服务器都在一个 .R 文件中,.Rmd 在不同的文件中.

The UI and Server is all on one .R document, the .Rmd is in a different document.

我已拆分 UI 和服务器并发布,但仍然出错.

I have split the UI and the server and published and still error.

我在 R 中非常绿色且闪亮,但我尝试通过反复试验来学习.但在这里我完全卡住了.

Im very green in R and shiny but I try to learn by trial and error. But here i am stuck completly.

我只是想让它返回一个布局良好的文档

I just want it to return a nicely laid out document

这是我的会话:

sessionInfo()
R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] bindrcpp_0.2  knitr_1.17    markdown_0.8  prophet_0.2   Rcpp_0.12.12  ggplot2_2.2.1
[7] shiny_1.0.5  

loaded via a namespace (and not attached):
 [1] compiler_3.4.0       plyr_1.8.4           bindr_0.1            bitops_1.0-6        
 [5] tools_3.4.0          digest_0.6.12        evaluate_0.10.1      jsonlite_1.5        
 [9] tibble_1.3.4         gtable_0.2.0         pkgconfig_2.0.1      rlang_0.1.2         
[13] yaml_2.1.14          gridExtra_2.2.1      extraDistr_1.8.7     stringr_1.2.0       
[17] dplyr_0.7.3          tidyselect_0.2.0     stats4_3.4.0         rprojroot_1.2       
[21] grid_3.4.0           glue_1.1.1           inline_0.3.14        R6_2.2.2            
[25] rmarkdown_1.6        rstan_2.16.2         RJSONIO_1.3-0        purrr_0.2.3         
[29] tidyr_0.7.1          magrittr_1.5         backports_1.1.0      scales_0.5.0        
[33] codetools_0.2-15     htmltools_0.3.6      StanHeaders_2.16.0-1 rsconnect_0.8.5     
[37] assertthat_0.2.0     mime_0.5             xtable_1.8-2         colorspace_1.3-2    
[41] httpuv_1.3.5         labeling_0.3         stringi_1.1.5        RCurl_1.95-4.8      
[45] lazyeval_0.2.0       munsell_0.4.3   

提前感谢所有提供帮助的人.有些英雄不穿斗篷.

Thank you in advance to everyone that helps. Some heroes don't wear capes.

最佳

推荐答案

为什么将绘图作为参数传递可能会失败

将绘图保存为变量对于 ggplots 和其他特殊绘图类型是可能的,但不适用于通常使用 plot() 函数生成的更一般的基础绘图".换句话说,plot() 的返回值没有意义,因为绘制 plot 是函数的副作用.

Why passing plots as parameters might fail

Saving plots as variables is possible for ggplots and other special plot types but not for the more general "base plots" that are usually produced with the plot() function. In other words, the return value of plot() is not meaningful because drawing the plot is a side effect of the function.

x <- plot(1:10)
x
#> NULL

因此有必要将这些副作用传递"给 rmarkdown 报告而不是返回值.

It is therefore necessary to "pass" these side-effects to the rmarkdown report rather than the return value.

传递副作用的一种方法是函数.为此,您首先定义一个绘制绘图的函数.然后将新定义的函数作为参数传递给Rmd-document

A way to pass side-effects is functions. For this, you first definine a function that draws the plot. Then the newly defined function is passed to the Rmd-document as a parameter

draw_plot <- function() {
  plot(1:10)
}
rmarkdown::render(
  "template.Rmd",
  params = list(draw_plot = draw_plot)
)

现在可以在 Rmd 文档中调用该函数,并且将在那里(重新)绘制该图.一般来说,可以在参数化报告 和函数(闭包)对于此类用例来说是一种非常灵活的对象类型.

The function can now be called inside the Rmd-document and the plot will be (re-)drawn there. Generally speaking, it is possible to pass any R object as a parameter in parameterized reports and functions (closures) are a very flexible object type for use-cases like this.

但是请注意,某些绘图库确实允许将绘图存储在变量中.在这些情况下,函数不是必需的.您只需要传递生成绘图的函数的返回对象.

Notice however, that some plotting libraries do allow to store plots in variables. In those cases a function is not necessary. You just need to pass the return-object of the function that generates the plot.

library(ggplot2)

gg <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
class(gg)
#> [1] "gg"     "ggplot"

rmarkdown::render(
  "template.Rmd",
  params = list(plot_object = gg)
)

可重现的示例

这是一个完整的应用程序来演示此设置.确保应用可以找到"报告

Reproducible example

Here is a full app to demonstrate this setup. Make sure that the app can "find" the Report

  • 将应用程序和 Rmd 文档放在同一个文件夹中
  • 使用 runApp("path/to/app.R") 调用应用程序或使用 RStudio 中的运行应用程序"按钮.
  • Put the app and the Rmd document into the same folder
  • Invoke the app with runApp("path/to/app.R") or use the "Run App" button in RStudio.
library(shiny)

ui <- fluidPage(
  textInput("main", "main", "main"),
  plotOutput("plot"),
  downloadButton("download_button")
)

server <- function(input, output, session) {
  draw_plot <- function() {
    plot(1:10, main = input$main)
  }
  output$plot <- renderPlot({
    draw_plot()
  })
  output$download_button <- downloadHandler(
    filename = "rendered_report.pdf",
    content = function(file) {
      res <- rmarkdown::render(
        "template.Rmd",
        params = list(
          draw_plot = draw_plot
        )
      )
      file.rename(res, file)
    }
  )
}

shinyApp(ui, server)

模板.Rmd

---
output: pdf_document
params:
  draw_plot: NULL
---

```{r}
if (!is.null(params$draw_plot))
  params$draw_plot()
```

这篇关于在 Shiny 中下载 PDF 报告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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