在 r + shiny 中生成传递用户定义参数的独立动态报告

Generating independent dynamic reports passing user-defined parameters in r + shiny

我想要一个闪亮的应用程序,让用户能够根据用户定义的参数下载同一报告的多个版本。以 iris 数据集为例,其想法是为每个用户定义的数据集子集(由 Species)生成报告。

我的报告代码 (test.Rmd) 如下:

---
title: "Parametrised report"
output: pdf_document
params:
   species: 
      label: Species
      input: select
      choices: [setosa, versicolor, virginica]
---

```{r}
df <- dplyr::filter(iris, Species %in% params$species)

library(ggplot2)
ggplot(df, aes(Sepal.Length, Petal.Length)) + geom_point()
```

我的 app.R 文件代码如下:

# Define the ui code
ui <- bootstrapPage(

selectInput('species', 'Select species:',
          paste(unique(iris$Species)),
          multiple = TRUE),

downloadButton('DownloadReport')

)


# Define the server code
server <- function(input, output) {

flower_species <- reactive({input$species})

observe({
lapply(flower_species(), function(i) {
  output$DownloadReport <- downloadHandler(

    filename = paste0('test_', i, '.pdf'),

    content = function(file) {

      out <- rmarkdown::render('test.Rmd', rmarkdown::pdf_document(), params = list(species = i))
      file.rename(out, file)

    }

  )
})
})

}

# Return a Shiny app object
shinyApp(ui = ui, server = server)

用户将定义物种(setosa, versicolor, virginica 中的一个或多个),如果选择了多个物种,则报告不仅会将数据子集化为每个报告仅包含该物种(df <- dplyr::filter(iris, Species %in% params$species) ),但将为每个选定的物种生成一份新报告。

我找到了这个 link:Shiny: dynamic UI - a loop around downloadHandler? which builds on this discussion: https://groups.google.com/forum/#!msg/shiny-discuss/qGN3jeCbFRY/xOW5qoVrr94J,但这并不是我所需要的 - 我不想要多个下载按钮,而是一个创建独立报告的下载按钮输入 selectInput。我希望上面显示的 lapply 方法可行,但只创建了一份报告。此外,我尝试了一种循环方法,但没有奏效(错误消息是我试图在反应环境之外做一些反应)。

我很惊讶在任何地方都找不到它 - 它似乎在许多闪亮的应用程序中都有用。非常感谢任何帮助。

我设法获得了一个工作版本,但它在 RStudio 预览器中不起作用,您必须单击 Show in browser 按钮。

我认为您需要删除 test.Rmd 中 YAML 中此处不需要的某些部分:

---
title: "Parametrised report"
output: pdf_document
params:
   species: setosa
---

```{r}
df <- dplyr::filter(iris, Species %in% params$species)

library(ggplot2)
ggplot(df, aes(Sepal.Length, Petal.Length)) + geom_point()
```

app.R 看起来像这样:

library(magrittr)

# Define the ui code
ui <- bootstrapPage(

  selectInput('species', 'Select species:',
              paste(unique(iris$Species)),
              multiple = TRUE),

  downloadButton('DownloadReport')

)


# Define the server code
server <- function(input, output) {

  flower_species <- reactive({input$species})

  output$DownloadReport <- downloadHandler(
    filename = "test.zip",
    content = function(file){
      files <- lapply(flower_species(), function(i) {
        rmarkdown::render('test.Rmd', rmarkdown::pdf_document(), output_file = paste0(i, ".pdf"), params = list(species = i))
      }) %>% unlist %>% basename
      zip(file, files)
      file

    }
  )
}

# Return a Shiny app object
shinyApp(ui = ui, server = server)

基本上和你之前写的原理一样,只是lapply循环在downloadHandler content元素里面,你用zip函数把所有生成的报表压缩到返回的单个 zip 文件。也许在 zip 之后抛出一个 unlink 以删除所有 pdf。