r - 延迟 downloadHandler 直到生成图
问题描述
我想使用 Shiny 应用程序中各个选项卡中的图表生成 R Markdown 报告。
只有在用户激活选项卡后,才会生成每个选项卡中的图。如果之前未激活选项卡,则该图将不存在,因此无法用于报告。
因此,我尝试在调用 downloadHandler 之前使用 updateTabsetPanel 连续打开所有选项卡。然而,与手动单击选项卡相反,空选项卡会打开,并且文件下载对话框会在绘图开始渲染之前立即出现。只有在保存报告文件后,Shiny 才会开始渲染绘图并且报告是空的。
有没有办法强制 downloadHandler 等到所有选项卡中的所有绘图完成渲染?
这是一个例子:
应用程序.R
library(shiny)
library(ggplot2)
ui <- fluidPage(
mainPanel(
tabsetPanel(id = "tabs",
tabPanel("Plot1",
downloadButton("report", "create report"),
plotOutput("plot1")
),
tabPanel("Plot2", plotOutput("plot2")),
tabPanel("Plot3", plotOutput("plot3"))
)
)
)
server <- function(input, output, session) {
plots <<- list()
output$plot1 <- renderPlot({
plots[[1]] <<- ggplot(mtcars, aes(wt, mpg)) + geom_point()
plot(plots[[1]])
})
output$plot2 <- renderPlot({
plots[[2]] <<- ggplot(mtcars, aes(wt, cyl)) + geom_point()
plot(plots[[2]])
})
output$plot3 <- renderPlot({
plots[[3]] <<- ggplot(mtcars, aes(wt, disp)) + geom_point()
plot(plots[[3]])
})
output$report <- downloadHandler(
filename = ("report.html"),
content = function(file) {
updateTabsetPanel(session, "tabs", selected = "Plot1")
updateTabsetPanel(session, "tabs", selected = "Plot2")
updateTabsetPanel(session, "tabs", selected = "Plot3")
tempReport <- file.path(tempdir(), "report.rmd")
file.copy("report.rmd", tempReport, overwrite = TRUE)
params <- list(plots = plots)
rmarkdown::render(tempReport, output_file = file, params = params, envir = new.env(parent = globalenv()))
}
)
}
shinyApp(ui, server)
报告.rmd
---
title: "report"
output: html_document
params:
plots: NA
---
```{r}
for (i in params$plots)
plot(i)
```
在这种情况下,为了简单起见,我将 tabPanel 调用放在 downloadHandler 中。他们应该打开所有选项卡,以便渲染绘图,然后,rmarkdown 可以绘制它们。
如果单击“报告”按钮,将打开第 3 个选项卡,并且在呈现选项卡 2 和 3 的图之前出现文件对话框,因此报告仅包含图 1。但是如果您手动单击所有 3 个选项卡,然后单击“报告”,所有绘图都将被渲染并包含在报告中。
解决方案
尝试:
output$plot1 <- renderPlot({
plots[[1]] <<- ggplot(mtcars, aes(wt, mpg)) + geom_point()
plot(plots[[1]])
})
outputOptions(output, "plot1", suspendWhenHidden = FALSE)
output$plot2 <- renderPlot({
plots[[2]] <<- ggplot(mtcars, aes(wt, cyl)) + geom_point()
plot(plots[[2]])
})
outputOptions(output, "plot2", suspendWhenHidden = FALSE)
output$plot3 <- renderPlot({
plots[[3]] <<- ggplot(mtcars, aes(wt, disp)) + geom_point()
plot(plots[[3]])
})
outputOptions(output, "plot3", suspendWhenHidden = FALSE)
编辑
以上不起作用。以下作品。
library(shiny)
library(ggplot2)
ui <- fluidPage(
mainPanel(
tabsetPanel(id = "tabs",
tabPanel("Plot1",
downloadButton("report", "create report"),
plotOutput("plot1")
),
tabPanel("Plot2", plotOutput("plot2")),
tabPanel("Plot3", plotOutput("plot3"))
)
)
)
server <- function(input, output, session) {
plots <- vector("list", length = 3L)
plots[[1L]] <- reactive({
ggplot(mtcars, aes(wt, mpg)) + geom_point()
})
plots[[2L]] <- reactive({
ggplot(mtcars, aes(wt, cyl)) + geom_point()
})
plots[[3L]] <- reactive({
ggplot(mtcars, aes(wt, disp)) + geom_point()
})
output$plot1 <- renderPlot({
plots[[1L]]()
})
output$plot2 <- renderPlot({
plots[[2L]]()
})
output$plot3 <- renderPlot({
plots[[3L]]()
})
output$report <- downloadHandler(
filename = "report.html",
content = function(file) {
tempReport <- file.path(tempdir(), "report.rmd")
file.copy("report.rmd", tempReport, overwrite = TRUE)
params <- list(plots = plots)
rmarkdown::render(
tempReport, output_file = file, params = params,
envir = new.env(parent = globalenv())
)
}
)
}
shinyApp(ui, server)
报告.Rmd:
---
title: "report"
output: html_document
params:
plots: NA
---
```{r}
for(plot in params$plots)
print(plot())
```
推荐阅读
- python - 如何在我们自己的数据集上使用 TensorFlow
- c# - Accord .Net 读取 .mat 文件错误的数据类型或值
- python - 如何获取图像的标题和主题属性?
- reactjs - 无法使用 React + Jest + Datepicker + TextMask 读取 null 的属性“selectionEnd”
- docker - 如何为 OnlyOffice 正确设置 HTTPS
- regex - Apache重定向保留URL
- django - 在 ListView url 上显示 CreateView 表单
- r - 根据列表过滤行
- javascript - Electron 预加载函数而不是外部文件?
- javascript - 用于弹出类别列表的 JavaScript 不起作用