Generate and render rmd from within shinyapp

770 views Asked by At

I wrote a shiny app that includes generating an rmd file and then rendering it into html report.

As shown in the simple example below, there is a variable created inside the server function of shinyapp, then the created rmd file should have access to this variable while rendering into html.

according to other posts and articles, it seems that we have to copy the rmd file into a temporary folder to work and that's what I tried to do below.

the app is not working. when I try locally, I get this error:

Quitting from lines 8-9 (x3.Rmd) 

Warning: Error in print: object 'xz' not found

so it seems that shiny was able to find the generated rmd, started rendering it but did not have access to the xz variable generated in shiny. I did some reading, and it seems to be related to the render environment (ie it renders in a new session) but I do not know how to fix that. (in the real app I am working on, the render process should have access to a dataframe not just a string variable, but I believe the concept is the same for illustration purpose).

when I tested on shinyapps.io, it says Failed-server problem when I click on the download button. Surprisingly, there is nothing in the application log, it says currently no logs.

when I test the original app I am writing (not this simple example), I get this error in shinyapp.io logs:

2022-04-10T18:01:45.357461+00:00 shinyapps[6055802]: Warning in normalizePath(path, winslash = winslash, mustWork = mustWork) :
2022-04-10T18:01:45.357710+00:00 shinyapps[6055802]:   [No stack trace available]
2022-04-10T18:01:45.357627+00:00 shinyapps[6055802]: Warning: Error in abs_path: The file '/tmp/Rtmp27RVU8/x3.Rmd' does not exist.
2022-04-10T18:01:45.357543+00:00 shinyapps[6055802]:   path[1]="/tmp/Rtmp27RVU8/x3.Rmd": No such file or directory

My goal is to make this work from shinyapp.io. Any suggestions on where to go from there, I believe there are two issues: 1- make sure the rmd render will have access to the variables generated in shiny 2- save the rmd file in a place that is "convenient" for shiny to find and render.


library(shiny)

ui <- fluidPage(
  
  downloadButton("report", "Download sample report.")
  
  
)

server <- function(input, output, session) {
  
  
  #create content and export it into rmd
  
  observe({
    
    xz=  "hello there"
    
    
    
    x3 = '--- 
title: sample
output: html_document
---


``` {r}
print(xz)
```

';write(x3, file="x3.rmd", append = FALSE)
    
    
  })
  


  #Render the report and pass it to download handler
  output$report <- downloadHandler(
    
    filename = "sample.html",
    
    content = function(file) {
      
      tempReport <- file.path(tempdir(), "x3.Rmd")
      file.copy("x3.Rmd", tempReport, overwrite = TRUE)
      
      
      output <- rmarkdown::render(
        input = tempReport
      )
      file.copy(output, file) 
      
      
      
      
    })
  
  
}

shinyApp(ui, server)

These are the resources I used (but still unable to make it work). All deal with parameterized reports of a user uploaded .rmd, which won't work in my case:

https://shiny.rstudio.com/articles/generating-reports.html https://community.rstudio.com/t/where-do-i-save-the-rmd-file-i-am-generating-with-a-shiny-r-app/65987/3 https://community.rstudio.com/t/generating-downloadable-reports/39701

https://mastering-shiny.org/action-transfer.html#downloading-reports

1

There are 1 answers

1
anuanand On

I have done this with Shiny App but on a shiny server (in my work place) and can share only the approach here. Currently the access to exact code will take time but this shall give you idea. No idea how it works with shinyapps.io but will try that sometime.

Within UI of shiny provide for a "Generate Report" Button.

In server, with

observeEvent(input$btn_Id,{

#Code to render the html in rmarkdown and then also `downloadHandler()`

})

Please check this also : Use the downloandHanlder() referring this documentation. This one gives idea to download data

Solution to passing variables is not special. Just ensure data is already present when you are calling render() like this:

rmarkdown::render(input = "D:/YourWorkingDirectly/Letters.rmd")

If this doesn't help you , please let me know and will delete the answer.