R Shiny/R Markdown: render() 在 downloadHandler 中失败
R Shiny/R Markdown: render() fails inside downloadHandler
我有一个 RMarkdown 模板,template.Rmd
:
---
title: "Template"
output: tufte_handout
params:
data: !r data.frame()
---
```{r setup, include=FALSE}
library(ggplot2)
knitr::opts_chunk$set(echo = TRUE)
```
# Title
## Another Title
```{r echo=FALSE}
ggplot(data = params$data, mapping = aes(x=params$data$X, y=params$data$Y)) +
geom_point()
```
然后我有了这个 R Shiny 应用程序,app.R
:
library(shiny)
library(rmarkdown)
data <- data.frame(X = 1:10, Y = 11:20)
ui <- fluidPage(fluidRow(column(
width = 6,
actionButton("actionButton", "PDF"),
downloadButton("downloadButton", "PDF")
)))
server <- function(input, output) {
observeEvent(input$actionButton, {
renderedFile <- render(
input = "template.Rmd",
output_format = "tufte::tufte_handout",
params = list(data = data),
output_file = "output.pdf"
)
browseURL(renderedFile)
})
output$downloadButton <-
downloadHandler(filename <- "output.pdf",
content <-
function(file) {
renderedFile <- render(
input = "template.Rmd",
output_format = "tufte::tufte_handout",
params = list(data = data),
output_file = "output.pdf"
)
file.copy(renderedFile, file)
})
}
shinyApp(ui = ui, server = server)
有一个 actionButton
和一个 downloadButton
。他们都应该或多或少地做同样的事情:呈现 PDF(准确地说是 Tufte 讲义),然后分别打开并下载它。虽然 browseURL
在我的机器上 运行 示例时工作得很好,但当 运行 在 "real" 服务器中运行应用程序时,我需要 downloadHandler
。
actionButton
完美运行,但 downloadButton
失败:
"C:/PROGRA~2/Pandoc/pandoc" +RTS -K512m -RTS template.utf8.md --to latex --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output pandoc7146d9cfc5.pdf --template "C:\Users\paedubucher\Documents\R\win-library.4\tufte\rmarkdown\templates\tufte_handout\resources\tufte-handout.tex" --highlight-style pygments --latex-engine pdflatex --variable "documentclass:tufte-handout"
! Undefined control sequence.
<argument> C:\temp
\RtmpAtAlbM \file 714614f62c3_files
l.78 ...62c3_files/figure-latex/unnamed-chunk-1-1}
pandoc.exe: Error producing PDF
Warning: running command '"C:/PROGRA~2/Pandoc/pandoc" +RTS -K512m -RTS template.utf8.md --to latex --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output pandoc7146d9cfc5.pdf --template "C:\Users\paedubucher\Documents\R\win-library.4\tufte\rmarkdown\templates\tufte_handout\resources\tufte-handout.tex" --highlight-style pygments --latex-engine pdflatex --variable "documentclass:tufte-handout"' had status 43
Warning: Error in : pandoc document conversion failed with error 43
Stack trace (innermost first):
53: pandoc_convert
52: convert
51: render
50: download$func [C:\Users\paedubucher\Documents\R\pdf-download/app.R#28]
1: runApp
Error : pandoc document conversion failed with error 43
编辑:现在有正确的错误消息。 Pandoc 失败(错误 43),但是当它在 actionButton
上下文中 运行 时一切正常。
GitHub pointed out the problem 上友好的 R Shiny 朋友们。 output_file
不应该以这种方式使用。它只是中间的 LaTeX 文件。 PDF 文件的位置从 render
返回。这个文件只需要移动到 file
参数指向的地方:
output$downloadButton <-
downloadHandler(
filename = "output.pdf",
content =
function(file) {
output <- render(
input = "template.Rmd",
output_format = "tufte::tufte_handout",
params = list(data = data)
)
file.copy(output, file)
}
)
我有一个 RMarkdown 模板,template.Rmd
:
---
title: "Template"
output: tufte_handout
params:
data: !r data.frame()
---
```{r setup, include=FALSE}
library(ggplot2)
knitr::opts_chunk$set(echo = TRUE)
```
# Title
## Another Title
```{r echo=FALSE}
ggplot(data = params$data, mapping = aes(x=params$data$X, y=params$data$Y)) +
geom_point()
```
然后我有了这个 R Shiny 应用程序,app.R
:
library(shiny)
library(rmarkdown)
data <- data.frame(X = 1:10, Y = 11:20)
ui <- fluidPage(fluidRow(column(
width = 6,
actionButton("actionButton", "PDF"),
downloadButton("downloadButton", "PDF")
)))
server <- function(input, output) {
observeEvent(input$actionButton, {
renderedFile <- render(
input = "template.Rmd",
output_format = "tufte::tufte_handout",
params = list(data = data),
output_file = "output.pdf"
)
browseURL(renderedFile)
})
output$downloadButton <-
downloadHandler(filename <- "output.pdf",
content <-
function(file) {
renderedFile <- render(
input = "template.Rmd",
output_format = "tufte::tufte_handout",
params = list(data = data),
output_file = "output.pdf"
)
file.copy(renderedFile, file)
})
}
shinyApp(ui = ui, server = server)
有一个 actionButton
和一个 downloadButton
。他们都应该或多或少地做同样的事情:呈现 PDF(准确地说是 Tufte 讲义),然后分别打开并下载它。虽然 browseURL
在我的机器上 运行 示例时工作得很好,但当 运行 在 "real" 服务器中运行应用程序时,我需要 downloadHandler
。
actionButton
完美运行,但 downloadButton
失败:
"C:/PROGRA~2/Pandoc/pandoc" +RTS -K512m -RTS template.utf8.md --to latex --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output pandoc7146d9cfc5.pdf --template "C:\Users\paedubucher\Documents\R\win-library.4\tufte\rmarkdown\templates\tufte_handout\resources\tufte-handout.tex" --highlight-style pygments --latex-engine pdflatex --variable "documentclass:tufte-handout"
! Undefined control sequence.
<argument> C:\temp
\RtmpAtAlbM \file 714614f62c3_files
l.78 ...62c3_files/figure-latex/unnamed-chunk-1-1}
pandoc.exe: Error producing PDF
Warning: running command '"C:/PROGRA~2/Pandoc/pandoc" +RTS -K512m -RTS template.utf8.md --to latex --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output pandoc7146d9cfc5.pdf --template "C:\Users\paedubucher\Documents\R\win-library.4\tufte\rmarkdown\templates\tufte_handout\resources\tufte-handout.tex" --highlight-style pygments --latex-engine pdflatex --variable "documentclass:tufte-handout"' had status 43
Warning: Error in : pandoc document conversion failed with error 43
Stack trace (innermost first):
53: pandoc_convert
52: convert
51: render
50: download$func [C:\Users\paedubucher\Documents\R\pdf-download/app.R#28]
1: runApp
Error : pandoc document conversion failed with error 43
编辑:现在有正确的错误消息。 Pandoc 失败(错误 43),但是当它在 actionButton
上下文中 运行 时一切正常。
GitHub pointed out the problem 上友好的 R Shiny 朋友们。 output_file
不应该以这种方式使用。它只是中间的 LaTeX 文件。 PDF 文件的位置从 render
返回。这个文件只需要移动到 file
参数指向的地方:
output$downloadButton <-
downloadHandler(
filename = "output.pdf",
content =
function(file) {
output <- render(
input = "template.Rmd",
output_format = "tufte::tufte_handout",
params = list(data = data)
)
file.copy(output, file)
}
)