I would like to display a slider (in below example, bins
) in the sidepanel only if a certain radio button is selected (in below example, y
).
library(shiny)
ui <- fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
width = 3,
radioButtons("modify_hist", "Modify histogram?", choices=c("Yes"="y", "No"="n"), selected="y"),
# display below sliderInput only if input$modify_hist=="y"; otherwise do not display below sliderInput
sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)),
mainPanel(
plotOutput("distPlot")
)
)
)
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
}
shinyApp(ui = ui, server = server)
(No need to hide the plot for this example.)
I tried selecting input$modify_hist
in the sidebarPanel
but that didn't work.
Any pointers are appreciated. Thank you!
CodePudding user response:
We can use conditionalPanel
which is faster than renderUI
as it avoids re-rendering the element:
library(shiny)
ui <- fluidPage(titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
width = 3,
radioButtons(
"modify_hist",
"Modify histogram?",
choices = c("Yes" = "y", "No" = "n"),
selected = "y"
),
conditionalPanel(
"input.modify_hist == 'y'",
sliderInput(
"bins",
"Number of bins:",
min = 1,
max = 50,
value = 30
)
)
),
mainPanel(plotOutput("distPlot"))
))
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins 1)
hist(x,
breaks = bins,
col = 'darkgray',
border = 'white')
})
}
shinyApp(ui = ui, server = server)
CodePudding user response:
Alternative to the other answer: You can generate the UI in the server, and only generate the bin slider based on the value of input$modify_hist
. I also included req(input$bins)
in your renderPlot function, to make sure it does not try to plot with having a value for input$bins
.
library(shiny)
ui <- fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
width = 3,
radioButtons("modify_hist", "Modify histogram?", choices=c("Yes"="y", "No"="n"), selected="y"),
# display below sliderInput only if input$modify_hist=="y"; otherwise do not display below sliderInput
uiOutput("slider")
),
mainPanel(
plotOutput("distPlot")
)
)
)
server <- function(input, output) {
output$distPlot <- renderPlot({
req(input$bins)
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
output$slider <- renderUI({
if(input$modify_hist == "y"){
sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
}
})
}
shinyApp(ui = ui, server = server)
CodePudding user response:
Also can do it with shinyjs
. I am all for using conditionalPanel
so all the work is on the client side...
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
width = 3,
radioButtons("modify_hist", "Modify histogram?", choices=c("Yes"="y", "No"="n"), selected="y"),
# display below sliderInput only if input$modify_hist=="y"; otherwise do not display below sliderInput
hidden(sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30))),
mainPanel(
plotOutput("distPlot")
)
)
)
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
observeEvent(input$modify_hist,{
if(input$modify_hist=="y"){
show("bins")
}else{
hide("bins")
}
})
}
shinyApp(ui = ui, server = server)