【问题标题】:Shiny interactive document download button overwrites original R markdown闪亮的交互式文档下载按钮覆盖原始 R 降价
【发布时间】:2017-04-20 10:22:06
【问题描述】:

所以我正在尝试编写一个带有交互式闪亮位的 html R markdown 文档,允许用户编辑图形,然后将结果下载到 pdf。但是,我尝试执行此操作的方式存在一些灾难性的错误,因为一旦 html 启动,它就会用 pdf 的内容覆盖原始降价文件 - 将其变成完全乱码在编辑器中。

我怀疑我是否找到了一种在 R 中失败的全新方法,但我无法找到其他人在哪里遇到过这个问题。此外,我已经查看了闪亮的参考资料,此时我只是在兜圈子,所以任何帮助都将不胜感激。

我使用的是 Rstudio 1.0.44、rmarkdown 1.2 和闪亮的 0.14.2。一个小(不)工作的例子:

---
title: "Minimum Failing Example"
author: "wittyalias"
date: "December 5, 2016"
output: html_document
runtime: shiny
---

```{r echo = FALSE}
library(ggplot2)

today <- Sys.Date()

inputPanel(downloadButton("dnld", label = "Download pdf"))

renderPlot({
    # Example code from http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/
    p1 <<- ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet, group=Chick)) +
    geom_line() +
    ggtitle("Growth curve for individual chicks")
    p1
})

reactive({
    fname <- paste0("Chick Weight - ", today, ".pdf")

    output$dnld <- downloadHandler(filename = fname,
                    content = makethepdf(file))

    makethepdf <- function(fname) {
        pdf(fname,
            width = 14,
            height = 8.5)
        p1
        dev.off()
}
})
```

编辑:明确一点:我希望用户能够下载多页图表,其中一些会有不同的格式。用户不会只下载降价文档的 pdf 版本。

【问题讨论】:

    标签: r shiny rstudio r-markdown


    【解决方案1】:

    发生这种情况是因为我无法识别 makethepdf 使用 file = [name of the file] 运行的原因。插入print(fname) 即可查看。下载处理程序不应该在观察者内部。你需要把它放在外面。由于某种原因,我也未能使 pdf() dev.off() 组合工作,所以下面是一个工作版本。

    output$dnld = downloadHandler(filename =  paste0("Chick Weight - ", today, ".pdf"),
                              content = function(file){
                                  ggsave(file, plot = p1, width = 14, height = 8.5)
                              })
    

    【讨论】:

    • 非常感谢您的建议,但我需要在 pdf 中制作多个页面,据我所知,ggsave 不允许我这样做。此外,我在 makethepdf 函数的外部和内部都插入了print(fname),它返回了我所期望的“Chick Weight....pdf”。
    【解决方案2】:

    使用tempfile()tempdir() 创建临时文件:

     output$downloadReport = downloadHandler(
    
        filename = function() {
          normalizePath(tempfile("report_", fileext = ".docx"), winslash = "/")
        },
    
        content = function(file) {
    
        out = rmarkdown::render("./report.Rmd", 
                                output_file = file,
                                output_dir = tempdir(),
                                output_format = "pdf_document",
                                intermediates_dir = tempdir(),
                                envir = new.env(),
                                params = list( fontSize = 10)
      )
    })
    

    我通常为下载的报告使用单独的 .Rmd 模板,因为布局和文本通常与应用程序中的内容相似但不完全相同。

    我还发现使用参数是一种将输入设置从我的应用程序传递到我的报告的便捷方式。详情见this RStudio post

    【讨论】:

    • 这是个好主意,我不知道可以这样做。我明天会考虑使用它,但我不确定它是否会起作用。我只想包含图表,而不是完整的降价报告。这可能吗?
    【解决方案3】:

    好的,所以我的代码存在许多问题,但是使用其他答案中的一些建议,我已经能够解决它。

    这个小文档的主要问题是downloadHandler中的content是一个函数,但是在我的代码中我设置content等于函数调用的结果。看起来当闪亮的应用程序第一次运行时它编译content,认为它是一个函数,但实际上最终调用了该函数。它发送file 作为争论,除了作为基本函数之外似乎不存在。当我在控制台中使用file 时,仅使用file 调用makethepdf 会引发错误,但无论出于何种原因,在此应用程序中它都会与调用一起使用,显然是file = [name of the .Rmd](正如OganM 所说)。

    要修复,请更改:

    output$dnld <- downloadHandler(filename = fname,
                    content = makethepdf(file))
    

    output$dnld <- downloadHandler(filename = fname,
                    content = makethepdf)
    

    需要明确:如果content 使用除file 之外的任何参数调用makethepdf,则此代码不会覆盖.Rmd 文件。例如,content = makethepdf(fnm)) 导致下载按钮显示object not found 错误,content = makethepdf(fname)) 导致下载按钮在按下时抛出attempt to apply non-function 错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-06
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 2019-05-20
      • 2017-11-03
      相关资源
      最近更新 更多