observeEvent() function in R - 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)

Related

Change sliderbar color with setSliderColor within reactive output

I'm building a shiny app that has a reactive slider that I want the bar color to be red. I'm trying to use the setSliderColor() function from the shinyWidgets package, but it's not working. My assumption is that it isn't picking up on the sliderId because it isn't:
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
setSliderColor(c("green"), sliderId = c(1)),
sidebarLayout(
sidebarPanel(
textInput(inputId = "greeting",
label = "Say hi!"),
actionButton(inputId = "submit",
label = "Submit"),
uiOutput("num_slider"),
),
mainPanel()
))
server <- function(input, output) {
output$num_slider <- renderUI({
shiny::req(input$greeting)
shiny::req(input$submit)
if(input$greeting == "hi!") {
sliderInput(inputId = "num_filter2",
label = "Filter by Number",
min = 1,
max = 10,
value = c(1, 10))
} else {
sliderInput(inputId = "num_filter2",
label = "Filter by Number",
min = 1,
max = 5,
value = c(1, 5))
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
But, here's the weird thing. If I put in a regular slider in the UI, it suddenly detects both--but then changes the color back to blue if I click submit twice:
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
setSliderColor(c("green", "red"), sliderId = c(1, 2)),
sidebarLayout(
sidebarPanel(
textInput(inputId = "greeting",
label = "Say hi!"),
actionButton(inputId = "submit",
label = "Submit"),
uiOutput("num_slider"),
sliderInput(inputId = "num_filter1",
label = "Now it works!",
min = 1,
max = 10,
value = c(1, 10))
),
mainPanel()
))
server <- function(input, output) {
output$num_slider <- renderUI({
shiny::req(input$greeting)
shiny::req(input$submit)
if(input$greeting == "hi!") {
sliderInput(inputId = "num_filter2",
label = "Filter by Number",
min = 1,
max = 10,
value = c(1, 10))
} else {
sliderInput(inputId = "num_filter2",
label = "Filter by Number",
min = 1,
max = 5,
value = c(1, 5))
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
Any fix on how address this? I'm also open to other solutions if it avoids long bouts of HTML, like this answer.
The function is just not designed to work with renderUI(). The arguments need to be updated in each call.
a quick fix would be preallocate very large vectors that the user will never reach (like 1 million) or use reactiveValues() like this:
note: The sliders will turn green when "hi!" is passed as an input.
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
textInput(inputId = "greeting",
label = "Say hi!"),
actionButton(inputId = "submit",
label = "Submit"),
uiOutput("num_slider"),
sliderInput(inputId = "num_filter1",
label = "Now it works!",
min = 1,
max = 10,
value = c(1, 10))
),
mainPanel()
))
server <- function(input, output) {
i <- reactiveValues()
i$color <- 1
i$color_name <- 'green'
observeEvent(input$submit, {
i$color <- c(i$color, i$color[[length(i$color)]] + 1)
i$color_name <- c(i$color_name, 'green')
#left for demonstration purposes
print(i$color)
print(i$color_name)
shiny::req(input$greeting)
shiny::req(input$submit)
output$num_slider <- renderUI({
if(input$greeting == "hi!") {
fluidPage(setSliderColor(i$color_name, sliderId = i$color),
sliderInput(inputId = "num_filter2",
label = "Filter by Number",
min = 1,
max = 10,
value = c(1, 10)))}
}) })
}
# Run the application
shinyApp(ui = ui, server = server)

Shiny button needed only once

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)

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.

R shiny plots based on radio buttons and slider input

Based on this post:
create plots based on radio button selection R Shiny
I want a different plot output depending on which radio option the user selects and adjust the numbers of committees using the slider input.
The slider input doesn't work and I don't realize how to solve the problem.
Many thanks for the help!
Here is my code:
library(shiny)
library(Cubist)
plotType <- function(x, type, committe) {
switch(type,
Cond = dotplot(finalModel, what = "splits"),
Coeff = dotplot(finalModel, what = "coefs"))
}
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
radioButtons(inputId = "ptype", label = "Select the plot", choices = c("Cond", "Coeff")),
sliderInput(inputId = "commit", min=1, max = 25, value = 2)
),
mainPanel(
plotOutput("plots"))
)))
server <- shinyServer(function(input, output) {
output$plots <-renderPlot({
plotType(finalModel, input$ptype, input$commit)
})
})
shinyApp(ui = ui, server = server)
Make sure to add lable to your sliderinput too:
library(shiny)
plotType <- function(x, type, committe) {
switch(type,Cond = dotplot(finalModel, what = "splits"),Coeff = dotplot(finalModel, what = "coefs"))
}
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
radioButtons(inputId = "ptype", label = "Select the plot", choices = c("Cond", "Coeff")),
sliderInput(inputId = "commit","", min=1, max = 25, value = 2)
),
mainPanel(
plotOutput("plots"))
)))
server <- shinyServer(function(input, output) {
output$plots <- renderPlot({
plotType(finalModel, input$ptype, input$commit)
})
})
shinyApp(ui = ui, server = server)
There is no need for comma at the end of this line:
sliderInput(inputId = "commit", min=1, max = 25, value = 2),
should be:
sliderInput(inputId = "commit", min=1, max = 25, value = 2)

Resources