Capturing select input in R Shiny? - r

I am trying to capture the url that has been selected when a person presses the "GET URLS" button on the app.
What should happen is that the event reactive() should look at the input$go_button and see that it has been pressed - it should then perform the expression to take the chosen url from the select input- unfortunately it does nothing.
I have tried debugging with browser() but still had no affect.
All i am trying to do is capture the url that has been selected when a person "presses" the "GET URLS" button.
my sample code is below:
library(shiny)
# Use a fluid Bootstrap layout
ui <- fluidPage(
# Give the page a title
titlePanel("testing select"),
# Generate a row with a sidebar
sidebarLayout(
# Define the sidebar with one input
sidebarPanel(
selectInput("url_selection", "select url:",
choices = c(
'/multi-task/',
"/personal-account",
"/paperless"
)
),
actionButton(inputId = "go_button", label = "Get URLS")
),
# Create a spot for the barplot
mainPanel(
textOutput(outputId = "urls_selected_print")
)
)
)
server <- function(input, output) {
url_capture <- reactive({eventReactive(eventExpr = input$go_button,
valueExpr = {
message("capturing url chosen in selectize input")
chosen_url <- input$url_selection
browser()
return(chosen_url)
})
})
}
shinyApp(ui, server)

You can use observeEvent to capture event when go_button has been pressed. You can store the selection in a reactiveVal which can be displayed in your output.
server <- function(input, output) {
rv <- reactiveVal(NULL)
observeEvent(input$go_button, {
message("capturing url chosen in selectize input")
rv(input$url_selection)
})
output$urls_selected_print <- renderText({rv()})
}

Small alternative to Ben's answer (you just have to remove reactive, because eventReactive is already reactive):
server <- function(input, output) {
url_capture <- eventReactive(eventExpr = input$go_button,
valueExpr = {
message("capturing url chosen in selectize input")
chosen_url <- input$url_selection
return(chosen_url)
})
output$urls_selected_print <- renderPrint({
url_capture()
})
}

Related

How to set reactive value to default in R Shiny?

I have a problem with updating a reactive value in shiny.
So what my app basically does, is to save textInputs from the user.
When the user decides to upload all text inputs, I want to reset the textInputs.
Following example code:
ui.R
ui <- fluidPage(
sidebarPanel(
textInput("words", "Please enter a word"),
actionButton("submit_new_word", "Save"), # this submits each single word
textOutput("submitted_new_words"), # this show all submitted words
actionButton("submit_upload", "Upload my Results") # this uploads all submitted words
)
)
server.R
server <- function(input, output, session) {
words_submitted <- paste("") # initial value
w_submitted <- eventReactive(input$submit_new_word, {
words_submitted <- paste(words_submitted, " ", input$words)
words_submitted <<- words_submitted
updateTextInput(session,
inputId = "words",
value = "")
return(words_submitted)
}, ignoreNULL=FALSE)
output$submitted_new_words <- renderText({
w_submitted()
})
observeEvent(input$submit_upload, {
# saveData(data_final) # upload, not needed for example here
words_submitted <<- paste("")
})
}
If you try this minimal example, you will see that the text inputs will be resetted,
but only after the "Save" button is clicked again.
I however would like to have the text inputs to be resetted when the "submit_upload" button is clicked.
Does somebody have an idea?
You probably best to do it with some sort of reactive. The way shiny works is that if there is no reactivity attached to it wont invalidate (refresh) anything on the client side such as renderText
library(shiny)
ui <- fluidPage(
sidebarPanel(
textInput("words", "Please enter a word"),
actionButton("submit_new_word", "Save"), # this submits each single word
textOutput("submitted_new_words"), # this show all submitted words
actionButton("submit_upload", "Upload my Results") # this uploads all submitted words
)
)
v <- reactiveValues()
server <- function(input, output, session) {
v$words_submitted <- paste("") # initial value
observeEvent(input$submit_new_word, {
v$words_submitted <- paste(v$words_submitted, " ", input$words)
updateTextInput(session, inputId = "words",value = "")
}, ignoreNULL=FALSE)
output$submitted_new_words <- renderText({
v$words_submitted
})
observeEvent(input$submit_upload, {
# saveData(data_final) # upload, not needed for example here
v$words_submitted <- paste("")
})
}
# Run the application
shinyApp(ui = ui, server = server)

hiding a plot in shiny r [duplicate]

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)

One reactive function to be displayed on two different pages interactively

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.

How to validate user input in shiny

I'm working on a very simple Shiny app that takes in a DNA codon and returns the corresponding amino acid. My issue is that I want to validate the user input so that it can only accept 3 letter (a single codon), must be capital letters, and only accept the DNA bases ( A, C, T, or G). I've had a look at Shiny's validation article, but keep on running into errors.
Here is the code I have so far:
ui.R
library(shiny)
library(shinythemes)
shinyUI(fluidPage(
theme = shinytheme("slate"),
# Application title
titlePanel("Codon lookup"),
#
sidebarLayout(
sidebarPanel(
textInput(
inputId = "codon",
label = "Enter a codon",
value = ""),
actionButton(inputId = "go", label = "Search")
),
#
mainPanel(
verbatimTextOutput("aminoacid")
)
)
))
server.R
library(shiny)
library(Biostrings)
shinyServer(function(input, output) {
data <- eventReactive(input$go, {
#validate somehow
input$codon
})
output$aminoacid <- renderText({
GENETIC_CODE[[as.character(data())]]
})
})
Also, if anyone know of an easy way to retrieve the amino acid's full name, rather than just the single letter notation, that would be helpful. Any other suggestions are welcomed.
That reactive is not really the right place to do the validation in this case since you are not using GENETIC_CODE there. So I moved it into the renderText output node. If you had a reactive doing the lookup you could do it there.
I looked at GENETIC_CODE, and it seems to make more sense to do this as a dropdown anyway and use that as validation. So I went ahead and put a selectInput in there using renderUI, as you have more flexibility if you create the input control in the server usually.
I also moved the Search button to above the codon select control as it was getting covered up by the selection.
library(shiny)
library(shinythemes)
u <- shinyUI(fluidPage(
theme = shinytheme("slate"),
# Application title
titlePanel("Codon lookup"),
#
sidebarLayout(
sidebarPanel(
actionButton(inputId = "go", label = "Search"),
uiOutput("codonselection")
),
#
mainPanel(
verbatimTextOutput("aminoacid")
)
)
))
library(Biostrings)
s <- shinyServer(function(input, output) {
data <- eventReactive(input$go, {
input$codon
})
output$codonselection <- renderUI({
choices <- names(GENETIC_CODE)
default <- "TTC"
selectInput("codon",label="Select Codon",choices=choices,selected=default)
})
output$aminoacid <- renderText({
lookupcodon <-as.character(data())
if (lookupcodon %in% names(GENETIC_CODE)){
return(GENETIC_CODE[[ lookupcodon ]])
} else {
return("Name not in GENETIC_CODE")
}
})
})
shinyApp(u,s)
Screen shot of it working:

Hide/show outputs Shiny R

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)

Resources