Quick question on conditionalPanel for shiny/R.
Using a slightly modified code example from RStudio, consider the following simple shiny app:
n <- 200
# Define the UI
ui <- bootstrapPage(
numericInput('n', 'Number of obs', n),
conditionalPanel(condition = "input.n > 20",
plotOutput('plot') ),
HTML("Bottom")
)
# Define the server code
server <- function(input, output) {
output$plot <- renderPlot({
if (input$n > 50) hist(runif(input$n)) else return(NULL)
})
}
# Return a Shiny app object
shinyApp(ui = ui, server = server)
My objective is to hide the graph and move up the HTML text to avoid a gap. Now, you can see that if the entered value is below 20, the graph is hidden and the text "Bottom" is moved up accordingly. However, if the entered value is larger than 20, but smaller than 50, the chart function returns NULL, and while no chart is shown, the text "Bottom" is not moving up.
Question is: is there a way I can set a conditionalPanel such that it appears/is hidden based on whether or not a plot function returns NULL? The reason I'm asking is because the trigger a bit complex (among other things it depends on the selection of input files, and thus needs to change if a different file is loaded), and I'd like to avoid having to code it on the ui.R file.
Any suggestions welcome,
Philipp
Hi you can create a condition for conditionalPanel in the server like this :
n <- 200
library("shiny")
# Define the UI
ui <- bootstrapPage(
numericInput('n', 'Number of obs', n),
conditionalPanel(condition = "output.cond == true", # here use the condition defined in the server
plotOutput('plot') ),
HTML("Bottom")
)
# Define the server code
server <- function(input, output, session) {
output$plot <- renderPlot({
if (input$n > 50) hist(runif(input$n)) else return(NULL)
})
# create a condition you use in the ui
output$cond <- reactive({
input$n > 50
})
outputOptions(output, "cond", suspendWhenHidden = FALSE)
}
# Return a Shiny app object
shinyApp(ui = ui, server = server)
Don't forget to add the session in your server function and the outputOptions call somewhere in that function.
Related
I'm trying to write a calculator using Shiny in R for a video game (you input the stats of you and your opponent, and it outputs your odds of winning a match). However, I can't get the Shiny app to output any of my variables. The app runs fine, but nothing outputs when the action button is selected.
Trying to find the issue, I simplified my code into a basic calculator that takes a numeric input, multiplies it by two, and outputs a result. As before, nothing is displayed when the action button is pushed. However, if you directly type a string into the renderText function, it works just fine.
I need to include an action button in my ultimate code because I don't want it to calculate the result until several numerical values have been typed in. Could the action button be causing an issue somewhere, or is it something else?
Below is the simplified code. If I can get this to run, I'm sure I could get my more complicated code to run. Thank you!
library(shiny)
library(shinythemes)
ui <- fluidPage(
titlePanel("Multiply by 2"),
fluidRow(
column(12, textOutput("test"),
numericInput(inputId = "start", "Start", value = 1),
actionButton("go", "Go!") )
)
)
server <- function(input, output) {
myval <- reactiveValues()
observeEvent(input$go, {
reactive ({
if (input$go == 0)
return()
isolate({
myval$calc <- paste("The result is", 2*input$start)
})
})
})
output$test <- renderText({
if (input$go == 0)
return()
isolate({
myval$calc
})
})
}
shinyApp(ui = ui, server = server)
It looks like there is some extra code in there we don't need, for example the isolate function. See the below minimal example:
input$go doesn't tell us what the button is doing. Try running print(input$go) and have a look at the output.
library(shiny)
ui <- fluidPage(
titlePanel("Multiply by 2"),
fluidRow(
column(12,
textOutput("test"),
numericInput(inputId = "start", "Start", value = 1),
actionButton("go", "Go!")
)
)
)
server <- function(input, output) {
myval <- reactiveValues()
#Observe button (will run when the button is clicked)
observeEvent(input$go, {
myval$calc <- paste("The result is", 2 * input$start)
})
#Text output (will run when myval$calc changes)
output$test <- renderText({
myval$calc
})
}
shinyApp(ui = ui, server = server)
I am trying to find out how to show and hide my outputs like graphics and tabels each time when the user change something in the widgets. For instance I have a sliderInput for my variable called "gender" with 2 choices : male and female. I also have a button which executes estimations when the user click on it. I want to hide the outputs each time when the user changes at least one choice between the different widgets. For instance after one estimation the user decides to change only the level of education and when the user click on the sliderInput box, I would like to hide the previous results.
I tried to use the R package shinyjs and the functions hide/show but they are not working for outputs.
Do you have any idea how to do it without using shinyjs package?
Here is a part of my code:
shinyUI(fluidPage(
sidebarLayout(
fluidRow(
column(4, wellPanel(
fluidRow(
column(5,selectInput("gender",
label = div("Sexe",style = "color:royalblue"),
choices = list("Male", "Female"),
selected = "Female")),
# other different widjets..
column(8, plotOutput('simulationChange')),
column(4, tableOutput('simulationChangeTable'),
tags$style("#simulationChangeTable table {font-size:9pt;background-color: #E5E4E2;font-weight:bold;margin-top: 121px; margin-left:-30px;overflow:hidden; white-space:nowrap;text-align:left;align:left;}",
media="screen",
type="text/css"),
fluidRow(
column(6, tableOutput('simulationChangeEsperance'),
tags$style("#simulationChangeEsperance table {font-size:9pt;background-color: #E5E4E2;font-weight:bold;margin-top: -10px; margin-left:-30px;overflow:hidden; white-space:wrap;word-break: break-word;width:173px;text-align:left;}"))
)
)
)
)
)
))
shinyServer(function(input, output, session) {
# part of my server.R code
observe({
if (input$gender|input$age|input$birthplace|input$education){
shinyjs::hide("simulationChange")
shinyjs::hide("simulationChangeTable")
shinyjs::hide("simulationChangeEsperance")
}
})
Thank you.
The reason your code didn't work is because you didn't make a call to useShinyjs() (if you read the documentation or look at any examples of using shinyjs, you'll see that you HAVE to call useShinyjs() in the UI).
I couldn't replicate your code because it had too many errors, but just to demonstrate that it does work with outputs, here's a small example you can run. In your project, just add shinyjs::useShinyjs() somewhere in the UI.
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("hideshow", "Hide/show plot"),
plotOutput("plot")
)
server <- function(input, output, session) {
output$plot <- renderPlot({
plot(rnorm(100))
})
observeEvent(input$hideshow, {
# every time the button is pressed, alternate between hiding and showing the plot
toggle("plot")
})
}
shinyApp(ui = ui, server = server)
As mentioned by Dieter in the comments you need to use conditionalPanel. For example, in your ui.R, instead of
plotOutput('simulationChange')
use
conditionalPanel("output.show", plotOutput('simulationChange'))
And in your server.R add the following:
values <- reactiveValues()
values$show <- TRUE
observe({
input$gender
input$age
input$birthplace
input$education
values$show <- FALSE
})
output$show <- reactive({
return(values$show)
})
Also, don't forget to change values$show, when clicking on your button:
observeEvent(input$button, {
...
values$show <- TRUE
})
The other answers here don't seem to provide the right/complete answer. The solution is actually quite simple.
You need to use outputOptions(output, 'show', suspendWhenHidden = FALSE)
Below is a sample code that displays the text inside a conditionalPanel if the dropdown selection is 2 and hides if it is 1.
library(shiny)
ui <- fluidPage(
selectInput("num", "Choose a number", 1:2),
conditionalPanel(
condition = "output.show",
"The selected number is 2 so this text is displayed. Change it back to 1 to hide."
)
)
server <- function(input, output, session) {
output$show <- reactive({
input$num == 2 # Add whatever condition you want here. Must return TRUE or FALSE
})
outputOptions(output, 'show', suspendWhenHidden = FALSE)
}
shinyApp(ui = ui, server = server)
I have an application which has 3 tabItems. I want to use a slider on second page to display same result on 3rd page interactively, i.e. if 2nd page slider changes then 3rd page slider should also change respectively.
I have a reactive function on server side
choose_segment <- reactive({
Multiple conditions for dropdown{Due to security cant share the exact code.}
})
and this choose_segment is refered in UI once and now i want to use it on the third page as well, but when i am calling the function on third page it is not displaying any thing on ui and also not giving any error.
in UI it is called inside UIoutput.
uiOutput(choose_segment())
My observations : I think as per my study we can not call one function directly twice, so what i am doing is i have made two different functions and calling same function from them, i.e.
output$chooseSegment1 <- renderUI({
choose_segment()
})
output$chooseSegment2 <- renderUI({
choose_segment()
})
Issue : it is giving me output but they both are not interactive :(
Kindly provide a solution so that i can make both the sliders work in interactive manner.
I have faced the same scenario, in that i was suppose to change the code structure.
I made dynamic output uiOutput to the Dropdown menu ob ui and then used the same in my server as Input$xyz in observe on server and it worked for me.
Code :
UI : column(3, selectInput(inputId="ABC",label= "Choose ABC"))
column(3, selectInput(inputId="ABC1",label= "Choose ABC"))
Server : observe({
if(is.null(tab2_summary())) return(NULL)
updateSelectInput(session, "ABC", value = input$ABC)
})
observe({
updateSelectInput(session, "ABC1", value = input$ABC)
})
observe({
updateSelectInput(session, "ABC", value = input$ABC1)
})
So this is how i was able to make the selectInput interactive on two different page.
For your reference there is one full reproducible code.
Kindly refer,
library(shiny)
# UI ----------------------------------------------------------
ui <- navbarPage("Navbar!",
tabPanel("Plot", sidebarLayout(sidebarPanel(
radioButtons("yaxis1", "y-axis", c("speed"="speed", "dist"="dist"),
selected = "speed"
)),
mainPanel( plotOutput("plot"),
textOutput("test2")))), # for input checking
tabPanel("Summary", sidebarLayout(sidebarPanel(
radioButtons("yaxis2", "grouping-var", c("speed"="speed", "dist"="dist")
)),
mainPanel(
verbatimTextOutput("summary"),
textOutput("test1")
)))
)
# Server ------------------------------------------
server <- function(input, output, session) {
observe({
x <- input$yaxis1
updateRadioButtons(session, "yaxis2", selected = x)
})
observe({
y <- input$yaxis2
updateRadioButtons(session, "yaxis1", selected = y)
})
# output$test1 <- renderPrint({cat("yaxis1", input$yaxis1)})
# output$test2 <- renderPrint({cat("yaxis2", input$yaxis2)})
# output$plot <- renderPlot({ plot(cars[['speed']], cars[[input$yaxis1]]) })
# output$summary <- renderPrint({ summary(cars[[input$yaxis2]]) })
}
shinyApp(ui, server)
I Hope it will of your help.
I want to print a text first, before processing the code and then print a confirmation after the code is executed.
Here is my code (ui and server of app.R):
All unspecified variables are initiated within the app.R file.
ui <- fluidPage(
# Application title
titlePanel(h1("Order2Ship", align="center")),
# Sidebar iputs
sidebarLayout(
sidebarPanel( #LONG LIST OF INPUTS
),
# On Screen output
mainPanel(
textOutput("START"),
textOutput("Confirm")
)
)
)
# Underlining code for output (computes the whole each time an input is changed)
server <- function(input, output) {
observeEvent(input$Do, { # ignores all return values
output$START <- renderText({"Starting Analysis"})
O2S( #LONG LIST OF PARAMETERS, FROM INPUTS
)
output$Confirm <- renderText({"Analysis Done"})
})
}
# Run the application
shinyApp(ui = ui, server = server)
I do not need any returns from the function O2S, it basically takes one file as input and generates a solution file. But, both the text outputs are showing at the same time, after the function has run. I cannot figure it out. I just started out with Shiny, so sorry for such a naïve question.
Hi you can use shinyjs to create a chainevent something like this
library(shinyjs)
library(shiny)
ui <- fluidPage(
# Application title
titlePanel(h1("Order2Ship", align="center")),
# Sidebar iputs
sidebarLayout(
sidebarPanel( #LONG LIST OF INPUTS
actionButton(inputId = "Do",
label = "Start")
),
# On Screen output
mainPanel(
textOutput("START"),
textOutput("Confirm"),
useShinyjs()
)
)
)
# Underlining code for output (computes the whole each time an input is changed)
server <- function(input, output) {
startText <- eventReactive({input$Do},{
runjs("Shiny.onInputChange('analysisStarted',Date.now())")
"Starting Analysis"
},
ignoreInit = TRUE)
output$START <- renderText({startText()})
observeEvent(input$analysisStarted, { # ignores all return values
temp <- NULL
for(i in seq(50000)){
temp <- c(temp,i)
}
runjs("Shiny.onInputChange('analysisFinished',true)")
},
ignoreInit = FALSE)
confirmText <- eventReactive({input$analysisFinished},{
"Analysis Done"
},
ignoreInit = FALSE)
output$Confirm <- renderText({confirmText()})
}
# Run the application
shinyApp(ui = ui, server = server)
hope this helps!
I am trying to find out how to show and hide my outputs like graphics and tabels each time when the user change something in the widgets. For instance I have a sliderInput for my variable called "gender" with 2 choices : male and female. I also have a button which executes estimations when the user click on it. I want to hide the outputs each time when the user changes at least one choice between the different widgets. For instance after one estimation the user decides to change only the level of education and when the user click on the sliderInput box, I would like to hide the previous results.
I tried to use the R package shinyjs and the functions hide/show but they are not working for outputs.
Do you have any idea how to do it without using shinyjs package?
Here is a part of my code:
shinyUI(fluidPage(
sidebarLayout(
fluidRow(
column(4, wellPanel(
fluidRow(
column(5,selectInput("gender",
label = div("Sexe",style = "color:royalblue"),
choices = list("Male", "Female"),
selected = "Female")),
# other different widjets..
column(8, plotOutput('simulationChange')),
column(4, tableOutput('simulationChangeTable'),
tags$style("#simulationChangeTable table {font-size:9pt;background-color: #E5E4E2;font-weight:bold;margin-top: 121px; margin-left:-30px;overflow:hidden; white-space:nowrap;text-align:left;align:left;}",
media="screen",
type="text/css"),
fluidRow(
column(6, tableOutput('simulationChangeEsperance'),
tags$style("#simulationChangeEsperance table {font-size:9pt;background-color: #E5E4E2;font-weight:bold;margin-top: -10px; margin-left:-30px;overflow:hidden; white-space:wrap;word-break: break-word;width:173px;text-align:left;}"))
)
)
)
)
)
))
shinyServer(function(input, output, session) {
# part of my server.R code
observe({
if (input$gender|input$age|input$birthplace|input$education){
shinyjs::hide("simulationChange")
shinyjs::hide("simulationChangeTable")
shinyjs::hide("simulationChangeEsperance")
}
})
Thank you.
The reason your code didn't work is because you didn't make a call to useShinyjs() (if you read the documentation or look at any examples of using shinyjs, you'll see that you HAVE to call useShinyjs() in the UI).
I couldn't replicate your code because it had too many errors, but just to demonstrate that it does work with outputs, here's a small example you can run. In your project, just add shinyjs::useShinyjs() somewhere in the UI.
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("hideshow", "Hide/show plot"),
plotOutput("plot")
)
server <- function(input, output, session) {
output$plot <- renderPlot({
plot(rnorm(100))
})
observeEvent(input$hideshow, {
# every time the button is pressed, alternate between hiding and showing the plot
toggle("plot")
})
}
shinyApp(ui = ui, server = server)
As mentioned by Dieter in the comments you need to use conditionalPanel. For example, in your ui.R, instead of
plotOutput('simulationChange')
use
conditionalPanel("output.show", plotOutput('simulationChange'))
And in your server.R add the following:
values <- reactiveValues()
values$show <- TRUE
observe({
input$gender
input$age
input$birthplace
input$education
values$show <- FALSE
})
output$show <- reactive({
return(values$show)
})
Also, don't forget to change values$show, when clicking on your button:
observeEvent(input$button, {
...
values$show <- TRUE
})
The other answers here don't seem to provide the right/complete answer. The solution is actually quite simple.
You need to use outputOptions(output, 'show', suspendWhenHidden = FALSE)
Below is a sample code that displays the text inside a conditionalPanel if the dropdown selection is 2 and hides if it is 1.
library(shiny)
ui <- fluidPage(
selectInput("num", "Choose a number", 1:2),
conditionalPanel(
condition = "output.show",
"The selected number is 2 so this text is displayed. Change it back to 1 to hide."
)
)
server <- function(input, output, session) {
output$show <- reactive({
input$num == 2 # Add whatever condition you want here. Must return TRUE or FALSE
})
outputOptions(output, 'show', suspendWhenHidden = FALSE)
}
shinyApp(ui = ui, server = server)