Shiny button needed only once - button

I want an event to be triggered for the first time only by clicking a button. After that I want it to be reactive to the slider input.
I tried the following:
ui <- fluidPage(
actionButton("go", "Go"),
sliderInput("n", label = "Sample size", min = 1, max = 100, value = 10),
plotOutput('samples')
)
server <- function(input, output, session){
activate = reactive({FALSE})
activate = eventReactive(input$go, {
isolate(TRUE)
})
samples = eventReactive(activate(), {
rnorm(input$n)
})
output$samples <- renderPlot({ hist(samples()) })
}
shinyApp(ui = ui, server = server)
I hoped it would make it reactive to input$n after input$go has been clicked once. But it isn't and still needs input$go to be clicked every time.

There are several ways to achieve that.
One way would be to store the value in a reactiveValues() or just use req(), see below.
The problem with using eventReactive(activate(), ... is that it only triggers the code inside if activate() is executed, which only happens if you click input$go.
Reproducible example with req():
ui <- fluidPage(
actionButton("go", "Go"),
sliderInput("n", label = "Sample size", min = 1, max = 100, value = 10),
plotOutput('samples')
)
server <- function(input, output, session){
output$samples <- renderPlot({
req(input$go > 0)
hist(rnorm(input$n))
})
}
shinyApp(ui = ui, server = server)
Reproducible example with reactiveValues():
ui <- fluidPage(
actionButton("go", "Go"),
sliderInput("n", label = "Sample size", min = 1, max = 100, value = 10),
plotOutput('samples')
)
server <- function(input, output, session){
global <- reactiveValues(showPlot = FALSE)
observeEvent(input$go, {
global$showPlot <- TRUE
})
samples = reactive({
rnorm(input$n)
})
output$samples <- renderPlot({
req(global$showPlot)
hist(samples())
})
}
shinyApp(ui = ui, server = server)

Related

How to build a shiny app that shows the output ONLY when the user clicks a click button?

I want to build a simple shiny app, that takes a number input$number and prints this number only when the user clicks (input$click).
So far, I have tried this:
library(shiny)
ui = fluidPage(
sliderInput("number", "number", value = 10, min = 0, max = 50),
actionButton("click", "Change output"),
textOutput("text")
)
server = function(input, output, session) {
observeEvent(input$click, {
output$text = renderText({
print(input$number)
})
})
}
shinyApp(ui, server)
When the app launches for the first time, it waits for the user to click before it shows the output text. However, after clicking for the first time, the app does not care if you click or not, it will automatically show the chosen number with slider.
What am I missing?
You can use isolate to prevent reactivity
library(shiny)
ui = fluidPage(
sliderInput("number", "number", value = 10, min = 0, max = 50),
actionButton("click", "Change output"),
textOutput("text")
)
server = function(input, output, session) {
output$text = renderText({
input$click
req(input$click) #to prevent print at first lauch
isolate(print(input$number))
})
}
shinyApp(ui, server)
An alternative that I find helpful is to store values in a reactiveValues list and then update them using event observers.
library(shiny)
SLIDER_INIT <- 10
ui = fluidPage(
sliderInput("number", "number", value = SLIDER_INIT, min = 0, max = 50),
actionButton("click", "Change output"),
textOutput("text")
)
server = function(input, output, session) {
# Store values that will need to be displayed to the user here.
AppValues <- reactiveValues(
slider_number = 10
)
# Change reactive values only when an event occurs.
observeEvent(
input$click,
{
AppValues$slider_number <- input$number
}
)
# Display the current value for the user.
output$text = renderText({
AppValues$slider_number
})
}
shinyApp(ui, server)

observeEvent() function in R

I an super new to R and was exploring different buttons. I came acorss observe event and tried to use it, but it does not print my output. Can someone please help!
library(shiny)
ui <- fluidPage(
sliderInput(inputId = "num",
label = "Choose a number",
value = 25, min = 1, max = 100),
actionButton(inputId = "go", label = "Print Value")
)
server <- function(input, output) {
observeEvent(input$go,{as.numeric(input$num)})
}
shinyApp(ui = ui, server = server)
Note: The function is a part of the shiny library
If you want to print to the console you'll need to call print. If you rather want to print in the UI, you can do this with a reactiveVal:
library(shiny)
ui <- fluidPage(
sliderInput(inputId = "num",
label = "Choose a number",
value = 25, min = 1, max = 100),
actionButton(inputId = "go", label = "Print Value"),
textOutput("myText")
)
server <- function(input, output) {
printData <- reactiveVal()
observeEvent(input$go,{
print(input$num) # print to console
printData(input$num) # pass data to reactiveVal
})
output$myText <- renderText(printData())
}
shinyApp(ui = ui, server = server)

Hide plot when action button or slider changes in R Shiny

I have a small Shiny app that generates some data whenever the New data button is pressed. The Show plot button shows a hidden plot. I would like the plot to be hidden again automatically whenever the New data button is pressed to make a new data set. A bonus would be for the plot to be hidden also as soon as the slider is changed. I am not looking for a toggle action.
I tried adapting this example that uses conditional panel but I could not successfully figure out how to correctly change the values$show between TRUE and FALSE.
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "number",
label = "Pick a number",
min = 6,
max = 12,
value = 8),
actionButton("new_data",
"New data"),
actionButton("show_plot",
"Show plot")
),
mainPanel(
tableOutput("char_table"),
plotOutput(outputId = "car_plot")
)
)
)
server <- function(input, output) {
t <- eventReactive(input$new_data, {
r <- input$number
c <- r - 1
mat <- matrix(sample(0:1,r*c, replace=TRUE),r,c)
})
output$char_table <- renderTable({
t()
})
p <- eventReactive(input$show_plot, {
plot(cars)
})
output$car_plot <- renderPlot({
p()
})
}
shinyApp(ui = ui, server = server)
You can use a reactive value and a if to control the plot.
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "number",
label = "Pick a number",
min = 6,
max = 12,
value = 8),
actionButton("new_data",
"New data"),
actionButton("show_plot",
"Show plot")
),
mainPanel(
tableOutput("char_table"),
plotOutput(outputId = "car_plot")
)
)
)
server <- function(input, output) {
showPlot <- reactiveVal(FALSE)
t <- eventReactive(input$new_data, {
showPlot(FALSE)
r <- input$number
c <- r - 1
mat <- matrix(sample(0:1,r*c, replace=TRUE),r,c)
})
output$char_table <- renderTable({
t()
})
observeEvent(input$number, {
showPlot(FALSE)
})
observeEvent(input$show_plot, {
showPlot(TRUE)
})
output$car_plot <- renderPlot({
if (showPlot())
plot(cars)
})
}
shinyApp(ui = ui, server = server)
Alternate solution using shinyjs which is handy in these situations.
library(shiny)
library(shinyjs)
ui <- fluidPage( shinyjs::useShinyjs(),
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "number",
label = "Pick a number",
min = 6,
max = 12,
value = 8),
actionButton("new_data",
"New data"),
actionButton("show_plot",
"Show plot")
),
mainPanel(
tableOutput("char_table"),
plotOutput(outputId = "car_plot")
)
)
)
server <- function(input, output) {
t <- eventReactive(input$new_data, {
hide("car_plot")
r <- input$number
c <- r - 1
mat <- matrix(sample(0:1,r*c, replace=TRUE),r,c)
})
output$char_table <- renderTable({
t()
})
observeEvent(input$show_plot, {
show("car_plot")
})
output$car_plot <- renderPlot({
plot(cars)
})
}
shinyApp(ui = ui, server = server)

Using a reactive value in an IF-statement in the UI in R Shiny

I am trying to create a conditional UI in Shiny that depends on the input of a user. I specifically want to do the if in the UI part and NOT in the server part.
Here is an example of what I aim to accomplish.
# app.R
library(shiny)
ui <- shiny::fluidPage(
shiny::headerPanel(title = "Basic App"),
shiny::sidebarPanel(
shiny::sliderInput(inputId = "a",
label = "Select an input to display",
min = 0, max = 100, value = 50
)
),
if(output$out < 50){
shinyjs::hide(shiny::mainPanel(h1(textOutput("text"))))
}else{
shiny::mainPanel(h1(textOutput("text")))
}
)
server <- function(input, output) {
output$text <- shiny::renderText({
print(input$a)
})
var <- shiny::reactive(input$a)
output$out <- renderText({ var() })
}
shiny::shinyApp(ui = ui, server = server)
Is there a way that I can use the reactive value in the UI part of the function?
I think conditionalPanel could be a good solution for what you want to do
library(shiny)
ui <- shiny::fluidPage(
shiny::headerPanel(title = "Basic App"),
shiny::sidebarPanel(
shiny::sliderInput(inputId = "a",
label = "Select an input to display",
min = 0, max = 100, value = 50
)
),
shiny::mainPanel(
conditionalPanel(
condition = "input.a > 50",
h1(textOutput("text")))
)
)
server <- function(input, output) {
output$text <- shiny::renderText({
print(input$a)
})
}
shiny::shinyApp(ui = ui, server = server)
Hope this helps!!

Shiny Sliders Dependent on Single Checkbox

I have a Shiny App and I am trying to have two sliders appear only if the checkBox is selected. Below is the code I am trying to get to work and am not seeing the UI.
library(shiny)
ui <- fluidPage(
checkboxInput("box_checked", "box_checked", value = FALSE),
uiOutput("test")
)
# Define server logic
server <- function(input, output) {
output$test = renderUI({
if (input$box_checked = 0){
return(NULL)
}
if(input$box_checked = 1){
sliderInput("sliderOne", "Choose your value", min=0, max=100, value=50)
sliderInput("sliderTwo", "Choose your other value", min=0, max=50, value=25)
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
Try this way:
library(shiny)
ui <- fluidPage(checkboxInput("box_checked", "box_checked", value = FALSE),
uiOutput("test"))
# Define server logic
server <- function(input, output) {
output$test = renderUI({
if (input$box_checked == 0) {
return(NULL)
}
if (input$box_checked == 1) {
list(
sliderInput(
"sliderOne",
"Choose your value",
min = 0,
max = 100,
value = 50
),
sliderInput(
"sliderTwo",
"Choose your other value",
min = 0,
max = 50,
value = 25
)
)
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
I fixed if statement, as you used input$box_checked = 1 instead of input$box_checked == 1.
You should use list() to produce multiple UI elements inside renderUI.

Resources