R Shiny: multiple renderPlot calls in one R markdown document - r

BACKGOUND:
You can "ask" RStudio to generate an example R Markdown Shiny document, which contains this sample code:
## Inputs and Outputs
You can embed Shiny inputs and outputs in your document.
Outputs are automatically updated whenever inputs
change. This demonstrates how a standard R plot can be
made interactive by wrapping it in the Shiny
`renderPlot` function. The `selectInput` and
`sliderInput` functions create the input widgets used to
drive the plot.
```{r, echo=FALSE}
inputPanel(
selectInput("n_breaks", label = "Number of bins:",
choices = c(10, 20, 35, 50), selected = 20),
sliderInput("bw_adjust", label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2)
)
renderPlot({
hist(faithful$eruptions, probability = TRUE, breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)", main = "Geyser eruption duration")
dens <- density(faithful$eruptions, adjust = input$bw_adjust)
lines(dens, col = "blue")
})
```
Note that this example does not make use of a folder containing ui.R and server.R.
PROBLEM:
If you copy this multiple times, the first one works as expected, and the later ones get displayed as well, but do not react to changes in the input parameters.
QUESTION:
How can you create an R Markdown document with multiple embedded plots like the above (without using external folders with ui.R and server.R), but ensuring that each one works interactively?

You must give different ids to your input elements, something like that :
First embedded shiny plot :
```{r}
inputPanel(
selectInput("n_breaks", label = "Number of bins:",
choices = c(10, 20, 35, 50), selected = 20),
sliderInput("bw_adjust", label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2)
)
renderPlot({
hist(faithful$eruptions, probability = TRUE, breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)", main = "Geyser eruption duration")
dens <- density(faithful$eruptions, adjust = input$bw_adjust)
lines(dens, col = "blue")
})
```
Second embedded shiny plot :
```{r}
inputPanel(
selectInput("n_breaks2", label = "Number of bins:",
choices = c(10, 20, 35, 50), selected = 20),
sliderInput("bw_adjust2", label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2)
)
renderPlot({
hist(faithful$eruptions, probability = TRUE, breaks = as.numeric(input$n_breaks2),
xlab = "Duration (minutes)", main = "Geyser eruption duration")
dens <- density(faithful$eruptions, adjust = input$bw_adjust2)
lines(dens, col = "blue")
})
```

As described for example in the RStudio Shiny Tutorial, the first parameter to widget functions is the widget name, which identifies the widget. Multiple widgets with the same name will not each be usable, which is why simply creating two copies of the example does not create two working copies.
To make it work, you must make the widget names unique in each inputPanel call, and then use this names in the renderPlot calls.

Related

Why does my app work locally, but not on shinyapps.io?

I'm trying to deploye my shiny app on shinyapps.io and I get this message :
"An error has occurred
The application failed to start (exited with code 1)."
I tried to commit setwd line and other stuff but yet I didn't find solution.
The issue might be a wrong file path ? Should I put the "read.csv" line into my server or ui function ?
Here is my code :
#setwd(dir = "/media/miles/MILES/Projets & Cours/Master_1/Semestre 2/lardjane/Shiny_app/Projet Shiny")
matches <- read.csv('./matches.csv', stringsAsFactors=FALSE, sep=",", header=TRUE)
matches <- matches[,c(3,6)]
#summary(matches)
matches$platformid <- as.factor(matches$platformid)
#levels(matches$platformid)
#install.packages('shiny')
library(shiny)
#install.packages('rsconnect')
library(rsconnect)
ui <- shinyUI(fluidPage(
# Give the page a title
titlePanel("Game time by server"),
# Generate a row with a sidebar
sidebarLayout(
# Define the sidebar with one input
sidebarPanel(
selectInput("region", "Server:",
choices=levels(matches$platformid)),
hr(),
selectInput(inputId = "n_breaks",
label = "Number of bins in histogram (approximate):",
choices = c(10, 20, 35, 50),
selected = 20),
hr(),
checkboxInput(inputId = "individual_obs",
label = strong("Show individual observations"),
value = FALSE),
checkboxInput(inputId = "density",
label = strong("Show density estimate"),
value = FALSE),
conditionalPanel(condition = "input.density == true",
sliderInput(inputId = "bw_adjust",
label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2)),
hr(),
helpText("Data from Kaggle (2014-2018) League of Legends Ranked Matches.")
),
# Create a spot for the barplot
mainPanel(
plotOutput("timePlot")
)
)
)
)
server <- function(input, output) {
# Fill in the spot we created for a plot
output$timePlot <- renderPlot({
# Render a histogramme
hist(matches[matches$platformid==input$region,2],
probability = TRUE,
breaks = as.numeric(input$n_breaks),
main = "Game Time",
ylab="",
xlab="Duration (seconds)")
if (input$individual_obs) {
rug(matches[matches$platformid==input$region,2])
}
if (input$density) {
dens <- density(matches[matches$platformid==input$region,2],
adjust = input$bw_adjust)
lines(dens, col = "blue")
}
})
}
shinyApp(ui = ui, server = server)
I would like to add one last request. I would like to display R code just below the plot. That can anyone can get access to both (app result and R code). Is that possible ?
Thank you in advance.
swd is not the way to solve this because of how the environments in Shiny (and R in general) work. When you launch Shiny you actually don't know what physical server your Shiny server is running on. So you need to use a generic solution.
Try this:
matches <- read.csv('./matches.csv',
stringsAsFactors=FALSE, sep=",", header=TRUE)
Per https://docs.rstudio.com/shinyapps.io/Storage.html, if the csv file is in the same location as the app, try :
matches <- read.csv('matches.csv', stringsAsFactors=FALSE, sep=",", header=TRUE)
However, I don't think this is your issue; I think the issue is in your rendering of the plot. You use the input$region to generate your histogram, but you don't provide a default value, so it starts as NULL, which causes an issue when you try to construct your histogram. You have 2 options to solve this.
Option 1 is to set a default value for input$region with:
selectInput("region", "Server:",
choices=levels(matches$platformid),
selected = levels(matches$platformid)[1]),
Option 2 is to use req() so that the histogram will not run if any of its required values are not truthy:
server <- function(input, output) {
# Fill in the spot we created for a plot
output$timePlot <- renderPlot({
req(input$region, input$n_breaks)
# Render a histogramme
hist(matches[matches$platformid==input$region,2],
probability = TRUE,
breaks = as.numeric(input$n_breaks),
main = "Game Time",
ylab="",
xlab="Duration (seconds)")
if (input$individual_obs) {
rug(matches[matches$platformid==input$region,2])
}
if (input$density) {
dens <- density(matches[matches$platformid==input$region,2],
adjust = input$bw_adjust)
lines(dens, col = "blue")
}
})
}

Shiny Server unable to open connection to any shiny application

When I attempt to connect to any shiny application on my webserver I receive the following error:
ERROR: cannot open the connection
I am currently storing the application within the /srv/shiny-server folder on the server and the folder does currently have the correct read/write permissions. Earlier when I uploaded my application it ran without issue but I made several changes and when I updated the files I suddenly started getting this error. I tried rolling back all of the changes but the error persisted and so eventually I attempted uploading an example application from the Shiny Website and that also gets the same error.
Here is the code for the sample application I'm currently trying to get working but I do not think that it is the issue:
ui.R
library(shiny)
bootstrapPage(
selectInput(inputId = "n_breaks",
label = "Number of bins in histogram (approximate):",
choices = c(10, 20, 35, 50),
selected = 20),
checkboxInput(inputId = "individual_obs",
label = strong("Show individual observations"),
value = FALSE),
checkboxInput(inputId = "density",
label = strong("Show density estimate"),
value = FALSE),
plotOutput(outputId = "main_plot", height = "300px"),
# Display this only if the density is shown
conditionalPanel(condition = "input.density == true",
sliderInput(inputId = "bw_adjust",
label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2))
)
server.R
library(shiny)
function(input, output) {
output$main_plot <- renderPlot({
hist(faithful$eruptions,
probability = TRUE,
breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)",
main = "Geyser eruption duration")
if (input$individual_obs) {
rug(faithful$eruptions)
}
if (input$density) {
dens <- density(faithful$eruptions,
adjust = input$bw_adjust)
lines(dens, col = "blue")
}
})
}
I opened up the logs for the application located in /var/log/shiny-server and it turned out that permission was being denied to the folder. After googling the problem I found this question which helped me solve the issue

Interpreting the 'eruptions' variable option for knitr chunk in RMarkdown

I have the following knitr chunk obtained from RStudio base Rmarkdown-Shiny runtime template:
```{r eruptions, echo=FALSE}
inputPanel(
selectInput("n_breaks", label = "Number of bins:",
choices = c(10, 20, 35, 50), selected = 20),
sliderInput("bw_adjust", label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2)
)
renderPlot({
hist(faithful$eruptions, probability = TRUE, breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)", main = "Geyser eruption duration")
dens <- density(faithful$eruptions, adjust = input$bw_adjust)
lines(dens, col = "blue")
})
```
What is the use of eruptions option in {r eruptions, echo=FALSE}
It is the name of the chunk.
You cannot give same name to different chunks.

Include reactive text in a R markdown shiny documents

I am a little lost and am unable to add a reactive test (te) in the shiny output of an R markdown document. A minimal example based on an R studio example is paste below.
Many thanks in advance!
Jean-Pierre
---
title: "Untitled"
runtime: shiny
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r eruptions, echo=FALSE}
inputPanel(
selectInput("n_breaks", label = "Number of bins:",
choices = c(10, 20, 35, 50), selected = 20),
sliderInput("bw_adjust", label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2)
)
renderText({te})
renderPlot({
startTime <- Sys.time()
# additional code goes here
endTime <- Sys.time() +1
te <- reactive(startTime - endTime)
hist(faithful$eruptions, probability = TRUE, breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)", main = "Geyser eruption duration")
dens <- density(faithful$eruptions, adjust = input$bw_adjust)
lines(dens, col = "blue")
})
```
I think you should use te <<- reactive(startTime - endTime) to define te outside the renderPlot, use renderText({te()}) instead of renderText({te}) because it is a reactive expression, and finally put renderText({te()}) to the end after it's definition.

Reloading Rmd Html Document with Shiny Widets

I am looking at using Shiny widgets in an R-markdown file. I find this example, ran it in markdown, and then saved it as Html. However when I load it, it renders the widgets twice, and then hangs.
Is there a way I can avoid this, or is it a bug/known limitation in the system?
Here is the code:
---
runtime: shiny
output: html_document
---
### Here are two Shiny widgets
```{r echo = FALSE}
selectInput("n_breaks", label = "Number of bins:",
choices = c(10, 20, 35, 50), selected = 20)
sliderInput("bw_adjust", label = "Bandwidth adjustment:",
min = 0.2, max = 2, value = 1, step = 0.2)
```
### ...that build a histogram.
```{r echo = FALSE}
renderPlot({
hist(faithful$eruptions, probability = TRUE, breaks = as.numeric(input$n_breaks),
xlab = "Duration (minutes)", main = "Geyser eruption duration")
dens <- density(faithful$eruptions, adjust = input$bw_adjust)
lines(dens, col = "blue")
})
```
It works fine when I compile it, but when I save it and then reload it into Chrome, IE, Edge, etc... I get this:

Resources