I have problems generating table of contents in the markdown generated by my shinyapp.
I have tried to set in the YAML toc = TRUE but it doesn't work.
the app is something like this, an interface where some data is uploaded and a markdown where some graphics are rendered.
the problem is that when generating the pdf, html or word the table of contents is not generated.
app.R
library(shiny)
library(dplyr)
library(qcc)
library(ggplot2)
library(readxl)
library(kableExtra)
library(knitr)
shinyApp(ui =
fluidPage(fileInput("file", "Cargar Datos", multiple = FALSE),
radioButtons('format', 'Formato del documento', c('PDF', 'HTML', 'Word'),inline = TRUE),
downloadButton('downloadReport')),
server = function(input, output, session){
myData <- reactive({ infile <- input$file
if(is.null(infile)) return(NULL)
data <- read_excel(infile$datapath)
data})
plotData <- function(){plot(myData}
output$downloadReport <- downloadHandler(
filename = function() {
paste('my-report', sep = '.', switch(
input$format, PDF = 'pdf', HTML = 'html', Word = 'docx'
))
},
content = function(file) {
src <- normalizePath('report.Rmd')
# temporarily switch to the temp dir, in case you do not have write
# permission to the current working directory
owd <- setwd(tempdir())
on.exit(setwd(owd))
file.copy(src, 'report.Rmd', overwrite = TRUE)
library(rmarkdown)
out <- render('report.Rmd', switch(
input$format,
PDF = pdf_document(), HTML = html_document(), Word = word_document()
))
file.rename(out, file)
}
)
########################################
####
})
report.Rmd
---
title: "title"
subtitle: "subtitle"
output:
toc: true
toc_depth: 4
number_sections: true
author:
- "a1"
- "a2"
date: "`r format(Sys.Date(), '%B %d, %Y')`"
params:
p1: "p1"
p2: "p2"
---
# section1
## section1.1
# section2
```{r}
plotData()
Try passing the options as arguments to the rendering function, e.g.
rmarkdown::render('report.Rmd', rmarkdown::pdf_document(toc = TRUE, toc_depth = 4, number_sections = TRUE))
answered by stefan in a comment on the question.
I am currently trying to generate and export a pdf file from a shiny app.
I generate a table by using kable (it works).
When I add kable_styling options to my table (kable_styling(latex_options = c("scale_down"))), it cannot generate my pdf file with this error :
Error : pandoc document conversion failed with error 43
Note : I have check my pandoc version is to date.
Any idea?
Thanks a lot
here is my input.rmd
---
title: ""
output: pdf_document
---
```{r echo=T}
library(kableExtra)
library(knitr)
dt <- mtcars[1:5, 1:4]
kable(cbind(dt,dt, dt, dt, dt), "markdown") %>%
kable_styling(latex_options = c("scale_down"))
kable(dt, format = "latex", booktabs = T, caption = "Demo Table") %>%
add_header_above(c(" ", "Group 1" = 2, "Group 2[note]" = 2)) %>%
add_footnote(c("table footnote"))
test3<-kable(dt, "markdown")
kable_styling(test3, font_size=14)
```
Tableau2
`r test3`
and the shiny app :
library(rmarkdown)
library(knitr)
shinyApp(
ui = fluidPage(
basicPage(
downloadButton('report'))
),
server = function(input, output) {
output$report = downloadHandler(
filename = 'myreport.pdf',
content = function(file) {
out = render('input.Rmd', clean = TRUE, encoding='utf-8')
file.rename(out, file) # move pdf to file for downloading
},
contentType = 'application/pdf'
)
}
)
I'm basing my code below on this page on R Studio on creating apps with downloadable reports. I've created the following app and .Rmd documents, which are both saved in the same directory:
app.R:
library(rmarkdown)
library(shiny)
shinyApp(
ui = fluidPage(
sliderInput("slider", "Slider", 1, 100, 50),
downloadButton("report", "Generate report")
),
server = function(input, output) {
output$report <- downloadHandler(
filename = "report.pdf",
content = function(file) {
tempReport <- file.path(tempdir(), "report.Rmd")
file.copy("report.Rmd", tempReport, overwrite = TRUE)
params <- list(n = input$slider)
render(tempReport, output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
}
)
report.Rmd:
---
title: "Dynamic report"
output: pdf_document
params:
n: NA
---
```{r}
# The `params` object is available in the document.
params$n
```
A plot of `r params$n` random points.
```{r}
plot(rnorm(params$n), rnorm(params$n))
```
When I click on the "Generate report" button, the file that gets saved is called "report", when in fact I named it "report.pdf". I end up having to add ".pdf" manually into the filename in order for my computer to recognize it as a PDF document.
Is there a reason why the filename doesn't match exactly what I specified? What else am I supposed to do?
Try to set the the contentType argument of downloadHandler to the correct MIME type, i.e. to "application/pdf".
I would like to download Report within Shiny App, which includes Plotly graph.
So far i have not found any answer on stackoverflow.
Till this moment im able to download the screenshot of Plotly but it appears only in my working directory and it is not sent to Rmarkdown.
Example code:
library(shiny)
library(plotly)
library(rsvg)
library(ggplot2)
d <- data.frame(X1=rnorm(50,mean=50,sd=10),X2=rnorm(50,mean=5,sd=1.5),Y=rnorm(50,mean=200,sd=25))
ui <-fluidPage(
title = 'Download report',
sidebarLayout(
sidebarPanel(
helpText(),
radioButtons('format', 'Document format', c('PDF', 'HTML', 'Word'),
inline = TRUE),
downloadButton('downloadReport'),
tags$script('
document.getElementById("downloadReport").onclick = function() {
var plotly_svg = Plotly.Snapshot.toSVG(
document.querySelectorAll(".plotly")[0]
);
Shiny.onInputChange("plotly_svg", plotly_svg);
};
')
),
mainPanel(
plotlyOutput('regPlot')
)
)
)
server <- function(input, output, session) {
output$regPlot <- renderPlotly({
p <- plot_ly(d, x = d$X1, y = d$X2,mode = "markers")
p
})
observeEvent(input$plotly_svg, priority = 10, {
png_gadget <- tempfile(fileext = ".png")
png_gadget <- "out.png"
print(png_gadget)
rsvg_png(charToRaw(input$plotly_svg), png_gadget)
})
output$downloadReport <- downloadHandler(
filename = function() {
paste('my-report', sep = '.', switch(
input$format, PDF = 'pdf', HTML = 'html', Word = 'docx'
))
},
content = function(file) {
src <- normalizePath('testreport.Rmd')
owd <- setwd(tempdir())
on.exit(setwd(owd))
file.copy(src, 'testreport.Rmd')
library(rmarkdown)
out <- render('testreport.Rmd', params = list(region = "Test"), switch(
input$format,
PDF = pdf_document(), HTML = html_document(), Word = word_document()
))
file.rename(out, file)
}
)
}
shinyApp(ui = ui, server = server)
and testreport.Rmd file:
---
title: "test"
output: pdf_document
params:
name: "Test"
region: 'NULL'
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
Any help would be appreciated, because there is not many sources and documentations about R Plotly.
Cheers
If out.png is downloaded to your working directory, you can modify the content function of your downloadHandler to move it to the temporary directory and add it to the report:
content = function(file) {
temp_dir <- tempdir()
tempReport <- file.path(temp_dir, 'testreport.Rmd')
tempImage <- file.path(temp_dir, 'out.png')
file.copy('testreport.Rmd', tempReport, overwrite = TRUE)
file.copy('out.png', tempImage, overwrite = TRUE)
library(rmarkdown)
out <- render(tempReport, params = list(region = "Test"), switch(
input$format,
PDF = pdf_document(), HTML = html_document(), Word = word_document()
))
file.rename(out, file)
}
Your testreport.Rmd could look like (more info here):
---
title: "test"
---
Here's the plot image.
![Plot image](out.png)
You could also pass the arguments of your plotly function in the render of your content function as explained here and use a parametrized Rmarkdown file but this only works for Html reports.
Depending on how deep you want to dive into this, I would suggest creating a .brew file with your shiny code and than you can have your user send the information to the brew file and create the plot. This would give you a static code file which is updated dynamically with new data, each time. The only draw back is that when you make changes to shiny you have to make the same changes to your brew file. The other option is to create a flex dashboard with rmarkdown using the new RStudio 1.0 which becomes a html file.
See (Create parametric R markdown documentation?) for brew example.
I have a tough time to figure out how i can use if statement inside the .Rmd file or so. I could not find anything on stackoverflow...
I am going explain on the example of this shiny app:
library(shiny)
library(markdown)
library(knitr)
server <- function(input, output) {
output$downloadReport <- downloadHandler(
filename = function() {
paste('my-report', sep = '.', switch(
input$format, PDF = 'pdf', HTML = 'html', Word = 'docx'
))
},
content = function(file) {
src <- normalizePath('report.Rmd')
owd <- setwd(tempdir())
on.exit(setwd(owd))
file.copy(src, 'report.Rmd', overwrite = TRUE)
out <- rmarkdown::render('report.Rmd',
params = list(text = input$text),
switch(input$format,
PDF = pdf_document(),
HTML = html_document(),
Word = word_document()
))
file.rename(out, file)
}
)
}
ui <- fluidPage(
tags$textarea(id="text", rows=20, cols=155,
placeholder="Some placeholder text"),
tabPanel("Data",
radioButtons('filter', h3(strong("Auswahlkriterien:")),
choices = list("WerkstoffNr" = 1,
"S-Gehalt" = 2),
selected = 1,inline=TRUE),
conditionalPanel(
condition = "input.filter == '1'",
column(6,
h4("WerkstoffNr auswaehlen:"),
selectInput("select", " ",
choices = seq(1,100,10))),
column(6,
h4("Abmessung auswaehlen:"),
selectInput("abmfrom", "Von:",choices=as.list(seq(20,110,10))),
selectInput("abmto", "Bis:",choices=as.list(seq(20,110,10))),
actionButton("button1", "Auswaehlen"))),
conditionalPanel(
condition = "input.filter == '2' ",
column(6,h4("S-Gehalt auswaehlen:"),
selectInput("sgehalt", "Von:",choices=seq(1,100,10)),
selectInput("sgehalt2", "Bis:",choices=seq(1,100,10))),
column(6,h4("Abmessung auswaehlen:"),
selectInput("abmfrom2", "Von:",choices=as.list(seq(20,110,10))),
selectInput("abmto2", "Bis:",choices=as.list(seq(20,110,10)))))
),
flowLayout(radioButtons('format', 'Document format', c('PDF','HTML', 'Word'),
inline = TRUE),
downloadButton('downloadReport'))
)
shinyApp(ui = ui, server = server)
report.Rmd (it is just this at the moment):
---
title: "Parameterized Report for Shiny"
output: html_document
params:
text: 'NULL'
---
# Some title
`r params[["text"]]`
I would like to inside of my RMarkdown Report to have the input from this part of shiny app:
tabPanel("Data",
radioButtons('filter', h3(strong("Auswahlkriterien:")),
choices = list("WerkstoffNr" = 1,
"S-Gehalt" = 2),
selected = 1,inline=TRUE),
conditionalPanel(
condition = "input.filter == '1'",
column(6,
h4("WerkstoffNr auswaehlen:"),
selectInput("select", " ",
choices = seq(1,100,10))),
column(6,
h4("Abmessung auswaehlen:"),
selectInput("abmfrom", "Von:",choices=as.list(seq(20,110,10))),
selectInput("abmto", "Bis:",choices=as.list(seq(20,110,10))),
actionButton("button1", "Auswaehlen"))),
conditionalPanel(
condition = "input.filter == '2' ",
column(6,h4("S-Gehalt auswaehlen:"),
selectInput("sgehalt", "Von:",choices=seq(1,100,10)),
selectInput("sgehalt2", "Bis:",choices=seq(1,100,10))),
column(6,h4("Abmessung auswaehlen:"),
selectInput("abmfrom2", "Von:",choices=as.list(seq(20,110,10))),
selectInput("abmto2", "Bis:",choices=as.list(seq(20,110,10)))))
)
As we can see there is an If statement inside (concerning filtering option). So it depends on the user which option would like to use to filter the data. I would like to have this option inside of my Report. Just smthg easily like:
if input.filter == 1
Werkstoffnummer: input$select
Abmessung: von input$abmfrom bis input$abmto
else
S : von sgehalt bis sgehalt2
Abmessung: von input$abmfrom2 bis input$abmto2
So in the report will be only printed (if input.filter ==1):
Werkstoffnummer: 1
Abmessung: von 20 bis 30
Thanks so much!
May be I not fully understand you but you can use something like
(example print different text insist on input filter)
---
title: "Untitled"
runtime: shiny
output: html_document
---
```{r eruptions, echo=FALSE}
radioButtons('filter', h3(strong("Auswahlkriterien:")),
choices = list("WerkstoffNr" = 1,
"S-Gehalt" = 2),
selected = 1,inline=TRUE)
conditionalPanel(
condition = "input.filter == '1'",
column(6,
h4("WerkstoffNr auswaehlen:")
))
conditionalPanel(
condition = "input.filter == '2' ",
column(6,h4("S-Gehalt auswaehlen:")))
```
Or use server side ( render UI , like here )
but you cant shared it like static html file :
*"Note: If you are familiar with R Markdown, you might expect RStudio to save an HTML version of an interactive document in your working directory. However, this only works with static HTML documents. Each interactive document must be served by a computer that manages the document. As a result, interactive documents cannot be shared as a standalone HTML file."
Update
If you want download static html
example
report.rmd
---
title: "Untitled"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r ,echo=FALSE}
if(input$filter==1){
h1(paste("1",input$ii))
}else{
h1(paste("2",input$ii))
}
```
Shiny
library(shiny)
ui=shinyUI(fluidPage(
radioButtons('filter', h3(strong("Auswahlkriterien:")),
choices = list("WerkstoffNr" = 1,
"S-Gehalt" = 2),
selected = 1,inline=TRUE),
numericInput("ii","1",0),
downloadButton('downloadReport')
))
server=shinyServer(function(input, output) {
output$downloadReport <- downloadHandler(
filename = function() {
paste('my-report', sep = '.', 'html' )
},
content = function(file) {
src <- normalizePath('report.Rmd')
# temporarily switch to the temp dir, in case you do not have write
# permission to the current working directory
owd <- setwd(tempdir())
on.exit(setwd(owd))
file.copy(src, 'report.Rmd')
library(rmarkdown)
out <- render('report.Rmd', html_document())
file.rename(out, file)
}
)
})
shinyApp(ui,server )
Report will contain 1 or 2 insist on radio button and ii input
It sounds like what you want is a template to generate the report. R Markdown is a format for pretty-printing reports rather than generating them.
For report generation, there’s ‹brew›. It lets you generate any file (including R Markdown) using a simple template language. In your case, you could do something like:
<% if (input.filter == 1) { %>
… normal R Markdown code here!
<% } %>
Save this as report.rmd.brew or similar; then, in your report generation code, you need to brew the template before rendering it:
brew::brew('report.rmd.brew', 'report.rmd')
It finds the variables from the current environment by default (this can be configured).