R shiny plot appear either in PDF or in dashboard - r

I have an R shiny which generates a dashboard with some plots.
I implemented a download button to download the report as a PDF using knitr. Here is part the problematic part of the code:
hist_pl <- reactive({
inFile <- input$file
if (is.null(inFile))
return(NULL)
dataf <- getDF()
h <- hist(dataf)
par(new = T)
plot(x = h$mids, y=ec(h$mids)*max(h$counts), col = rgb(0,0,0,alpha=0), axes=F,xlab=NA, ylab=NA)
})
output$hist1 <- renderPlot({
hist_pl()
})
The problem is as follow:
When I comment the 'renderPlot' part of the code, the histogram appears normally in the PDF report (but not in the dashboard). When I uncomment it, the histogram disappear from the PDF (and appear in the dashboard).
The code for the download button is fairly simple:
output$report = downloadHandler(
filename = 'myreport.pdf',
content = function(file) {
out = knit2pdf('input.Rnw', clean = TRUE)
file.rename(out, file) # move pdf to file for downloading
},
contentType = 'application/pdf'
)
and the input.Rnw file:
\documentclass{article}
\begin{document}
<<names>>=
input$Val1
input$Val2
#
<<>>=
#output$mpgPlot ## N.B. This threw an error! Cannot call an object like this from shiny
print(hist_pl())
#
<<>>=
print(hist_pl())
#
\end{document}
Can someone tell me what could the problem be?

Related

Rmarkdown - cannot render image in html report when downloaded from shiny apps

I'm trying to make a "downloadable html report" from my shiny app, however when I deploy the app to shinyapps.io and try to download the report, it fails because I can't render the image in the R markdown file. It works fine locally, which means I think the issue is to do with the relative file path.
Short example made for ease:
app.R
library(shiny)
library(dplyr)
library(tidyverse)
library(knitr)
library(here)
#load pca plots from working directory
pca <- list.files(pattern="*pca_check.png")
#move file to www folder for it to render correctly
dir.create("www")
file.copy(pca[[1]], "www")
#pca[[1]] is "sept_2021.pca_check.png"
##################
# Make Shiny App #
##################
ui <- fluidPage(titlePanel("QC output"),
navbarPage("Menu",
tabPanel("Report",
sidebarLayout(
sidebarPanel(downloadButton("report", "Generate report"), width=0
),
mainPanel(tags$h2("Ancestry prediction Peddy"),
a(img(src=pca[[1]], height = 500, width = 300, slign="center",
target="_blank"),
href=pca[[1]])
)))))
server <- function(input, output) {
output$report <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = "report.html",
content = function(file) {
tempReport <- file.path(tempdir(), "report.Rmd")
file.copy("report.Rmd", tempReport, overwrite = TRUE)
# Set up parameters to pass to Rmd document
params <- list(pca = pca[[1]])
rmarkdown::render(tempReport, output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
}
shinyApp(ui = ui, server = server)
NB: the image displays fine in the app when using this code:
a(img(src=pca[[1]], height = 500, width = 300, slign="center",
target="_blank"),
href=pca[[1]])
However, when generating the report, it fails...
report.Rmd
---
title: "Dynamic report"
output: html_document
params:
pca: NULL
---
PCA plot
```{r out.width="70%"}
knitr::include_graphics(here::here(pca))```
If it don't use here::here(pca) the code fails locally. However it's clearly giving the wrong path when deployed. So, instead I tried just:
knitr::include_graphics(pca)
That still fails when deployed. The full app is here: https://lecb.shinyapps.io/QC_sept_21/ and the image in question was successfully uploaded to https://lecb.shinyapps.io/QC_sept_21/sept_2021.pca_check.png, which implies I am referring to the correct directory... perhaps the markdown doesn't know what the "working directory" is?
Anyone have any idea how to get the image to render in the downloadable report please?
Many thanks!
knitr::rendr treats the folder where the .Rmd file sits as root. You are copying your report.Rmd to a temp folder. Thus, copying your png to the same temp folder and referencing it without here should do the trick remotely and locally:
Untested code snippet:
output$report <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = "report.html",
content = function(file) {
tmp_dir <- tempdir()
tempReport <- file.path(tmp_dir, "report.Rmd")
tmp_pic <- file.path(tmp_dir, pca[[1]])
file.copy("report.Rmd", tempReport, overwrite = TRUE)
file.copy(pca[[1]], tmp_pic, overwrite = TRUE)
# Set up parameters to pass to Rmd document
params <- list(pca = pca[[1]])
rmarkdown::render(tempReport, output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
and
---
title: "Dynamic report"
output: html_document
params:
pca: NULL
---
PCA plot
```{r out.width="70%"}
knitr::include_graphics(params$pca)
```

How to display R Shiny output in R Markdown?

I'm new to R markdown here and I am trying to create an R Shiny app which I can enter a list of names, and then download the output (like a name list) as HTML file. I am using R markdown to create the HTML file. Here are my sample codes:
R Shiny:
library(shiny)
ui <- list(
textInput("name", "Type new text input name", value = ""),
actionButton("btn", "click me to create text input"),
uiOutput("newInputs"),
downloadButton("download_report", "Download")
)
server <- function(input, output)
{
family_member <- reactiveValues(
add_family_info = list()
)
observeEvent(input$btn, {
newid <- paste(length(family_member$add_family_info))
family_member$add_family_info <- c(family_member$add_family_info, list(c(newid, input$name)))
family_member
})
output$newInputs <- renderUI({
lapply(family_member$add_family_info, function(a)
c(paste(a[2])))
})
output$download_report <- downloadHandler(
filename = "name.html",
content = function(file) {
tempReport <- file.path(tempdir(), "name.Rmd")
file.copy("name.Rmd", tempReport, overwrite = TRUE)
params <- list(report = uiOutput("newInputs"))
rmarkdown::render(tempReport, output_file = file,
params = params,
envir = new.env(parent = globalenv()))
}
)
}
runApp(list(ui = ui, server = server))
R Markdown:
---
runtime: shiny
output: html_document
params:
report: NA
---
\
\
# Member names
`r params$report`
Appreciate any help! Thanks in advance!!!!
If you are just using a Shiny to render an Rmarkdown document, you don't need the runtime of the document to be Shiny. This is only needed if the document itself will ultimately be a shiny app.
Looking at the download handler
params <- list(report = uiOutput("newInputs"))
The uiOutput function generates the html for the element. It doesn't retrieve the values (you can see this if you run execute it in the console by itself). Additionally newInputs just refers to the container for the text (it's not actually inputs). Instead, you would want to use the reactive value storing the list
params <- list(report = family_member$add_family_info)
However, since this will be printed it can't be an arbitrary R object. It has to be something that cat can handle. In this case family_member$add_family_info is a list of list. Try flattening it with something like
params <- list(report = unlist(family_member$add_family_info))

How to run the if condition when the file is pdf file

I am new to R language. I am trying to run the Tesseract OCR function if the uploaded file is pdf file, it seems like it always goes to the else part. I know there is an error in the if part but I have no clue to use what symbol.
Here are some part of the code
output$table <- renderTable({
if(is.null(input$file)) {return()}
read.table(file=input$file$datapath[input$file$name==input$Select], fill = TRUE, skipNul = TRUE)
# PDF file
if (input$file$datapath[input$file$name==input$Select] == "pdf"){
pdffile <- pdftools::pdf_convert(input$file$datapath[input$file$name==input$Select], dpi = 600)
text <- tesseract::ocr(pdffile)
}
# JPEG file
else{
eng <- tesseract("eng")
text <- tesseract::ocr(input$file$datapath[input$file$name==input$Select], engine = eng)
}
})

Shiny R, Using the downloadButton function

I'm trying to figure out how to use a downloadButton to download multiple content to one pdf file. I have in the ui the download button created:
downloadButton('downloadData', 'Download Data'))
and I am trying to get multiple plots and tables into one pdf file. I have in the server file the following
output$downloadData <- downloadHandler(
filename = function() {
paste('data-', Sys.Date(), '.pdf', sep=”)
}
but I think this will save multiple csv files. How do i download multiple plots and tables from renders such as
output$table<-renderTable({
P.Value<- c(lev.p,bart.p,turn.p,shap.p,jar.p,linm.p)
Test.Statistic<-c(lev.s,bart.s,turn.s,shap.s,jar.s,linm.s)
df<-data.frame(P.Value,Test.Statistic)
rownames(df, do.NULL = TRUE, prefix = "row")
rownames(df) <- c("Levene Test","Bartlett Test","Turning Point Test","Shapiro-Wilk Test","Jarque Bera Test","Linear Model Constant Drift Test")
df
})
,
output$qq.line<-renderPlot({
index<-1:length(lg.ret.vec())
model<-lm((lg.ret.vec())~ index)
plot(model,which=2,main="QQ plot of the residuals",xlab="Theoretical Quantiles")
qqline(rstandard(model),col="black")
})
,
output$histogram<-renderPlot({
hist(lg.ret(),main="Histogram of log returns",xlab="Log returns")
})
to name just a few.
You could take advantage of rmarkdown to make a report with all your plots, here is one example.
In your case you could use the following downloadHandler (code adapted from the link):
output$downloadData <- downloadHandler(
filename = function() {
paste('report', sep = '.','html')
},
content = function(file) {
src <- normalizePath('report.Rmd')
owd <- setwd(tempdir())
on.exit(setwd(owd))
file.copy(src, 'report.Rmd')
library(rmarkdown)
out <- render('report.Rmd',html_document())
file.rename(out, file)
}
)
And create a file called report.Rmd in the same folder as your server.R and ui.R:
report.Rmd
---
title: "Your report"
output: html_document
---
This is your plot
```{r echo=FALSE}
index<-1:length(lg.ret.vec())
model<-lm((lg.ret.vec())~ index)
plot(model,which=2,main="QQ plot of the residuals",xlab="Theoretical Quantiles")
qqline(rstandard(model),col="black")
```
This is your histogram
```{r echo=FALSE}
hist(lg.ret(),main="Histogram of log returns",xlab="Log returns")
```
you need to define content to download for downloadHandler. see http://www.inside-r.org/packages/cran/shiny/docs/downloadHandler
How do you mean you are trying to download plots and tables to a single csv file? Do you mean to merge the data? You may be confused about what a csv file is.

How do I download all plots from my shiny app

I would like users to be able to upload a file, see the graphs displayed and then offer them a download link where they can download all graphs as pdfs in a zip or tar file. I have managed to do all steps except for the last. It works for one graph but not for many.
Here is my code
shinyServer(function(input, output) {
#takes the uploaded file and transforms it into the way I want it
dataInput<-reactive({
inFile <- input$file1
if (is.null(inFile)) return(NULL)
data<-read.csv(inFile$datapath, fileEncoding="UTF-16", sep="\t")
data$date<-ymd(data$StartDate)
data$date2<-format(data$date,"%b %y")
})
#plot 1
plotInput1<-function(){
data <- dataInput()
dataByCountry<-aggregate(Queries~date+Category, sum,data=data)
ggplot(dataByCountry, aes(x=date, y=Queries, group=Category, color=Category))+geom_line(size=1.5)+
}
#plot 2
plotInput2<-function(){
data <- dataInput()
categoryQueries<-aggregate(Queries~date+Geo+Category, sum,data=data)
ggplot(categoryQueriesLastyear, aes(x=Category, y=Queries, fill="#3369e8"))+geom_bar(stat='identity', fill="#3369e8")+
}
#render plots
output$haha1 <- renderPlot({plotInput1()})
output$haha2 <- renderPlot({plotInput2()})
#I can download one plot but how do I donwload all of them?
output$foo <- downloadHandler(
filename ="graphs.pdf",
content = function(file) {
pdf(file, width=12, height=6.3)
print(plotInput1()
dev.off()
})
})
})
Any help would be highly appreciated

Resources