简体   繁体   中英

ShinyApp: How to pass plot from one module into another one in order to download it in a report?

I want to generate a report that include a plot from another module, but my code does not work.

I have checked few examples from other shiny developers, but my code does not work.

As far as I understand, I need to:

(1) return the plot the plot module

(2) pass it to the download server

(3) also need to include it in the main server (I don't understand the logic here, I need your help for explanation)

My minimal example:

# Module 1,
plot_ui <- function(id) {
  ns <- NS(id)
  tagList(
    plotOutput(ns("plot"))
    )
  }

plot_server <- function(id) {
  moduleServer(id, function(input, output, session) {
    myplot <- reactive({plot(x = mtcars$wt, y = mtcars$mpg)})
    output$plot <-renderPlot({
      myplot()
    })
    return(myplot)
  })
}

# Module 2
download_ui <- function(id) {
  ns <- NS(id)
  tagList(
    downloadButton(outputId = ns("report_button"),
                   label = "Generate report"
                   )
    )
}

download_server <- function(id, myplot) {
  moduleServer(id, function(input, output, session){
    output$report_button<- downloadHandler(
      filename = "report.html",
      content = function(file) {
        tempReport <- file.path(tempdir(), "myRport.Rmd")
        file.copy("myReport.Rmd", tempReport, overwrite = TRUE)
        params <- list(plot1 = myplot())
        rmarkdown::render(tempReport,
                          output_file = file,
                          params = params
                          )
        }
      )
    }
  )
}


# Application
library(shiny)
app_ui <- function() {
  fluidPage(
    plot_ui("plot_ui_1"),
    download_ui("download_ui_2")
    )
}

app_server <- function(input, output, session) {
  getPlot <- plot_server("plot_ui_1")
  download_server("download_ui_2", myplot = getPlot)
}

shinyApp(app_ui, app_server)

My markdown file

---
title: "Test"
output: html_document
params:
  plot1: NA
---

```{r}
params$plot1

Basically you have done everything right. However, to make you code work you have to render your Rmd in a new environment by adding envir = new.env(parent = globalenv()) to rmarkdown::render . See eg Generating downloadable reports . Moreover TBMK you can't pass a base R plot to an Rmd via params , ie while your code works no plot will be displayed in the rendered report. That's why I switched to ggplot2 :

# Module 1,
plot_ui <- function(id) {
  ns <- NS(id)
  tagList(
    plotOutput(ns("plot"))
  )
}

plot_server <- function(id) {
  moduleServer(id, function(input, output, session) {
    myplot <- reactive({
      #plot(x = mtcars$wt, y = mtcars$mpg)
      ggplot(mtcars, aes(wt, mpg)) +
        geom_point()
    })
    output$plot <-renderPlot({
      myplot()
    })
    return(myplot)
  })
}

# Module 2
download_ui <- function(id) {
  ns <- NS(id)
  tagList(
    downloadButton(outputId = ns("report_button"),
                   label = "Generate report"
    )
  )
}

download_server <- function(id, myplot) {
  moduleServer(id, function(input, output, session){
    output$report_button<- downloadHandler(
      filename = "report.html",
      content = function(file) {
        tempReport <- file.path(tempdir(), "myRport.Rmd")
        file.copy("myReport.Rmd", tempReport, overwrite = TRUE)
        params <- list(plot1 = myplot())
        rmarkdown::render(tempReport,
                          output_file = file,
                          params = params,
                          envir = new.env(parent = globalenv())
        )
      }
    )
  }
  )
}

# Application
library(shiny)
library(ggplot2)

app_ui <- function() {
  fluidPage(
    plot_ui("plot_ui_1"),
    download_ui("download_ui_2")
  )
}

app_server <- function(input, output, session) {
  getPlot <- plot_server("plot_ui_1")
  download_server("download_ui_2", myplot = getPlot)
}

shinyApp(app_ui, app_server)

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM