In my Markdown file I use Shiny widgets to set some parameter. Add the end of the document some reactive text should be shown, depending on the choosen parameter, changing when a parameter is changed. This text should be formatted with linebreaks. Output format is HTML. The following minimal example shows my approach, the screenshot below the outcome. Unfortunatelly without linebreaks.
How can I archieve linebreaks in reactive textoutput in R-Markdown?
---
title: 'Minimal example'
runtime: shiny
output:
html_document
---
```{r setup, include=FALSE}
library(knitr)
library(shiny)
knitr::opts_chunk$set(echo = F)
```
```{r}
selectInput("input1", label = "Input1",
choices = 1:5, selected = 1)
selectInput("input2", label = "Input2",
choices = 1:5, selected = 1)
```
```{r}
### Generate Parameter for report
renderText({
HTML(paste('Input1:', input$input1, '<br> Input2:', input$input2))
})
renderText({
paste('Input1:', input$input1, ' \\n Input2:', input$input2)
})
renderText({
paste('Input1:', input$input1, ' \n Input2:', input$input2)
})
renderText({
cat(paste('Input1:', input$input1, ' \n Input2:', input$input2))
})
```
Use renderUI in combination with HTML() instead:
renderUI({
HTML(paste('Input1:', input$input1, '<br> Input2:', input$input2))
})
Related
I would like to:
Click a Button to "Generate Report"
Start an animated gif, showing "Computing ..."
Begin long computation using an Rmd file that generates and downloads an HTML report and
Stop the animated gif.
I can do both independently but not in the desired sequence. Need help. Here is my code in two files:
Shiny code
library(shiny)
library(here)
here::here()
ui <- pageWithSidebar(
headerPanel("How to intgrate an animated gif using renderImage with download report example"),
sidebarPanel(
downloadButton("report", "Generate report")
),
mainPanel(
imageOutput("myImage") # this is a placeholder for image
)
)
server <- function(input, output, session) {
output$myImage <- renderImage({
outfile = here::here("www", "Computing2.gif")
# write(outfile, "outfiledup.gif")
# outfiledup = here::here("outfiledup.gif")
# outfiledup
#
# Return a list containing the filename
list(src = outfile,
contentType = 'image/gif',
width = 125,
height = 50,
alt = "This is alternate text")
}, deleteFile = FALSE) # TRUE)
input_file = "report.Rmd"
output_file = "report.html"
output$report <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = output_file, # "report.html", default filename of downloaded file
content = function(file) {
# Copy the report file to a temporary directory before processing it, in
# case we don't have write permissions to the current working dir (which
# can happen when deployed).
tempReport <- file.path(tempdir(), input_file) # "report.Rmd")
file.copy(input_file, tempReport, overwrite = TRUE)
# Set up parameters to pass to Rmd document
# params <- list(n = input$slider)
# Knit the document, passing in the `params` list, and eval it in a
# child of the global environment (this isolates the code in the document
# from the code in this app).
rmarkdown::render(tempReport, output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
}
shinyApp(ui, server)
here is my report.Rmd file.
---
title: "Report"
author: "ABC DEF"
date: "Aug, 2022"
output: html_document
---
params:
n: = NA
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
R Markdown
This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
summary(cars)
Including Plots
You can also embed plots, for example:
plot(pressure)
Note that the echo = FALSE parameter was added to the code chunk to prevent printing of the R code that generated the plot.
I just wanted to make the data (displayed in the shiny datatable) selected by user editable and eventually to save the user's updates to a file (e.g. such as an excel file), see the testing code below:
I checked the example/questions below(and a few others), but none of those used the reactive as the data source.
https://yihui.shinyapps.io/DT-edit/
Edit datatable in shiny with dropdown selection (for DT v0.19)
DT: Dynamically change column values based on selectinput from another column in R shiny app
The issue for the code below is: when I try to update the second cell, the updates I made in the first cell disappeared.
library(shiny)
library(DT)
#>
#> Attaching package: 'DT'
#> The following objects are masked from 'package:shiny':
#>
#> dataTableOutput, renderDataTable
ui <- fluidPage(
selectInput("data", "Select a dataset:", choices = c("iris", "mtcars")),
DTOutput("t1"),
actionButton("save", "Save")
)
server <- function(input, output, session) {
tempdf <- NULL
data <- reactive({
head(get(input$data))
})
output$t1 <- renderDT({
data()
}, editable = "cell")
proxyt1 <- dataTableProxy("t1")
observeEvent(input$t1_cell_edit, {
info <- input$t1_cell_edit
str(info)
tempdf <<- editData(data(), info)
# tempdf <<- editData(isolate(data()), info)
replaceData(proxyt1, tempdf, resetPaging = FALSE)
})
# observeEvent(input$save, {
# writexl::write_xlsx(tempdf, "~/test.xlsx")
# })
}
shinyApp(ui, server)
#> PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
Shiny applications not supported in static R Markdown documents
Created on 2022-05-23 by the reprex package (v2.0.1)
Thank you very much for your help.
I am trying to generate downloadable RMarkdown reports using Shiny. I have included radioButtons in the UI to allow the user to select the output format of the report (Word or PDF). The problem I am facing is that the format selection in the UI is not impacting the output format. The first choice in the radioButton statement is dictating the output format, i.e., currently the first choice in the list, choices=list("PDF", "Word"), is set to PDF, this is producing a PDF output regardless of what is selected in the UI. Similarly, if the first choice in the list is set to Word, choices=list("Word", "PDF"), then a Word document is the final output regardless of what is selected in the UI.
I am unsure what I doing wrong so I would really appreciate any help! I have provided some dummy code below.
Shiny UI/Server
# Load packages
suppressWarnings(suppressMessages(library(shiny)))
suppressWarnings(suppressMessages(library(tidyverse)))
suppressWarnings(suppressMessages(library(rmarkdown)))
suppressWarnings(suppressMessages(library(bookdown)))
suppressWarnings(suppressMessages(library(knitr)))
# Define data frame variables
countries = c("Canada", "United States of America", "Qatar", "Scotland", "Bangladesh")
capitals = c("Ottawa", "Washington, DC", "Doha", "Edinburgh", "Dhaka")
values = seq(1, 5, 1)
# Build data fram
df = data.frame(countries, capitals, values)
# User interface
ui = fluidPage(
# Define title for the app
titlePanel("Dummy example"),
# Sidebar layout with input and output definitions
sidebarLayout(
sidebarPanel(
selectInput("select_country", "Select Country:", choice = unique(df$countries)),
uiOutput("select_capital"),
radioButtons("format", "Summary Format:", choices=list("PDF", "Word"), inline=TRUE),
downloadButton("download_report", "Download Report")
),
mainPanel(
)
)
)
# Server logic
server = function(input, output, clientData, session) {
# Build capitals filter based on selected country
output$select_capital = renderUI({
df = df[df$countries == input$select_country, ]
choice = unique(df$capitals)
selectInput(
"select_capital",
"Select Capital:",
choices = choice
)
})
# Download report
output$download_report = downloadHandler(
filename = paste("report",
switch(input$format, "Word"="docx", "PDF"="pdf"), sep="."),
content = function(file) {
normalized_path = normalizePath("report.Rmd")
# Temporarily switch to a temp directory in case you do not have permission
# to the current working directory
owd = setwd(tempdir())
on.exit(setwd(owd))
file.copy(normalized_path, "report.Rmd", overwrite=TRUE)
# Set up parameters to pass to Rmd documents
params = list(countries = input$select_country,
capitals = input$select_capital,
format = input$format)
out = rmarkdown::render("report.Rmd",
switch(input$format, "PDF"=pdf_document(), "Word"=word_document()),
params=params,
envir=new.env())
file.rename(out, file)
}
)
}
# Run RShiny app
shinyApp(ui, server)
RMarkdown template
---
title: "Dummy example"
date: "`r format(Sys.time(), '%B %d, %Y')`"
output:
bookdown::pdf_document2:
toc: false
df_print: kable
extra_dependencies: ["float"]
bookdown::word_document2:
toc: false
classoption: twocolumn
params:
countries: NA
capitals: NA
format: NA
urlcolor: blue
always_allow_html: true
header-includes:
- \usepackage{booktabs}
- \usepackage{longtable}
- \usepackage{array}
- \usepackage{multirow}
- \usepackage{float}
- \usepackage{tabu}
---
```{r packages, echo=FALSE, eval=TRUE, message=FALSE, include=FALSE}
knitr::opts_chunk$set(fig.pos = "!H", out.extra = "")
# Load packages
library(tidyverse)
library(rmarkdown)
library(bookdown)
library(knitr)
library(flextable)
library(kableExtra)
```
```{r print-dataframe, echo=FALSE, eval=TRUE, message=FALSE, results="asis"}
# Print data frame
print(params$format)
if (params$format == "Word") {
# Use flextable if the output format is Word
flextable(df)
} else {
# Use kable if the output format if PDF
df = knitr::kable(df, booktabs=T, caption="Dummy example") %>%
kableExtra::kable_styling(latex_options=c("scale_down", "HOLD_position", "repeat_header"))
print(df)
}
```
I think the format of the rendered document is the one selected. Only the file name doesn't have the correct extension. That's because you have a reactive variable (input$format) in the filename argument of the downloadHandler. In such case, you have to use a function for filename. That is, replace
filename = paste("report", switch(input$format, "Word"="docx", "PDF"="pdf"), sep=".")
with
filename = function(){
paste("report", switch(input$format, "Word"="docx", "PDF"="pdf"), sep=".")
}
I am trying to use a download button in the input column of a flex dashboard to download a collection of charts rendered as *.pdf. The entire dashboard works just fine, and the download button renders properly; however, when I click the download button, the file that does get downloaded does not contain the intended charts. The warning I get from my Mac when it tries to open the file is that the file might be damaged or that it's a form that Preview (or Acrobat) doesn't recognize. The following is a highly redacted form of my code that contains the problematic sections. Any guidance on how to get charts to download in a flexdashboard as charts download in Shiny?
---
title: "My Model"
runtime: shiny
output:
flexdashboard::flex_dashboard:
theme: cerulean
vertical_layout: scroll
orientation: rows
---
```{r global, include=FALSE}
library(shiny)
library(shinyBS)
library(shinyWidgets)
library(flexdashboard)
library(tidyverse)
library(readxl)
library(knitr)
library(RColorBrewer)
source("MLHS_Distributions.R")
source("interp.R")
source("tooltips.R")
```
```{r Inputs}
downloadButton("downlaodReport","Price Comparision Report")
downloadHandler(filename = function() {
filename = paste0("ModelReport-", Sys.Date(), ".pdf")
},
content = function(file) {
pdf(file, width = 8.5, height = 6.14)
renderPrint({output$gg.prob.win.price()})
dev.off()
}
)
```
```{r priceProbWinChart}
renderPlot({
gg.prob.win.price <- --ggplot code--
plot(gg.prob.win.price)
})
```
I would like to create a Shiny-RMarkdown app which allows uploading own datasets. Datasets sometimes not only affect one chunk which can be re-rendered by renderPlot() (or similar) but sometimes two or more chunks. See the following example:
---
title: Render multiple chunks
output: html_document
runtime: shiny
---
```{r echo=FALSE}
library(shiny)
fileInput('file1', 'Choose your own CSV File instead of provided
data',accept=c('text/csv', 'text/comma-separated-values,text/plain',
'.csv'))
go1<-reactive({
dpath <- "CurrentBiologyData.txt"
if(!is.null(input$file1)){
dpath <- input$file1$datapath
}
CB.dat <- read.table(dpath, header = TRUE) #choose 'CurrentBiologyData.txt'
plot(CB.dat)
})
```
```{r echo=FALSE}
renderPlot({
go1()
})
```
```{r}
renderPlot({
print(CB.dat)
})
```
So I have three chunks which are affected if I upload a new dataset. The problem is that the third chunk does not see CB.dat which is filled in the first chunk:
Error: Object 'CB.dat' not found
Any ideas how I can make that work?
Applying to your example what I meant in my comment
Put the file reading in a reactive then use it wherever you need it
---
title: Render multiple chunks
output: html_document
runtime: shiny
---
```{r echo=FALSE}
library(shiny)
fileInput('file1', 'Choose your own CSV File instead of provided
data',accept=c('text/csv', 'text/comma-separated-values,text/plain',
'.csv'))
CB.dat<-reactive({
dpath <- "CurrentBiologyData.txt"
if(!is.null(input$file1)){
dpath <- input$file1$datapath
}
read.table(dpath, header = TRUE) #choose 'CurrentBiologyData.txt'
})
```
```{r echo=FALSE}
renderPlot(plot(CB.dat())
```
```{r}
renderTable(CB.dat())
```