Reputation: 133
I have this slider which depends on the choice you make in a drop-down menu. Changing this choice essentially amounts to switching between a zero-to-one and a 0%-to-100% scale and this has an impact on the plot. I would like the plot to react only after the rescaling is complete, but it seems that it's updated before the slider-value is rescaled and then again after the slider-value is rescaled. The result is fine, but the additional step doesn't look nice.
I couldn't find a solution online. Also, if this is caused by some kind of unnecessary detour in the code, I don't see it. What can I do?
I tried to reduce the code as much as possible...
library(shiny)
library(tidyverse)
library(ggplot2)
library(flexdashboard)
library(shinythemes)
library(shinyWidgets)
library(janitor)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
width = 2,
actionButton("do", "Draw Sample", width="100%"),
selectInput("type", label = "Type",
choices = c("A","B"), selected = "A"),
sliderInput("rate", label = "Rate",
min = 0, max = 1, value = 0.8, step = 0.01)
),
mainPanel(width = 10,uiOutput("distPlot"))
)
)
server <- function(input, output, session) {
sim_data <- function() {data.frame(n = 1:100, y = runif(100))}
v <- reactiveValues(data = NULL)
observeEvent(input$do, {v$data = sim_data()})
observeEvent(input$type, {
a = input$rate
if (input$type == "B")
{
updateSliderInput(session, "rate", label = "p",
min = 0, max = 100, value = a*100, step = 1)}
else
{
updateSliderInput(session, "rate", label = "r",
min = 0, max = 1, value = a/100, step = 0.01)}
},
ignoreInit = TRUE)
output$distPlot <- renderUI({
output$plot <- renderPlot({
a = input$rate
if (is.null(v$data)) {v$data = sim_data()}
if (input$type == "B") {
a = quantile(v$data$y, a/100, type = 7)
ggplot() +
geom_point(data = filter(v$data, y>a), aes(x = n, y = y), shape = 17, color = "firebrick1", size =4 ) +
geom_point(data = filter(v$data, y<=a), aes(x = n, y = y), shape = 16, color = "darkolivegreen4", size = 4) +
geom_abline(slope=0,intercept=a)
}
else {
ggplot() +
geom_point(data = filter(v$data, y>a), aes(x = n, y = y), shape = 17, color = "firebrick1", size = 4) +
geom_point(data = filter(v$data, y<=a), aes(x = n, y = y), shape = 16, color = "darkolivegreen4", size = 4) +
geom_abline(slope=0,intercept=a)
}
})
plotOutput("plot", width = 800, height = 800)
})
}
shinyApp(ui = ui, server = server)
Upvotes: 1
Views: 77
Reputation: 2835
You can use isolate
to shield reactive expressions against reactivity.
Replace the if
statement with the following,
if (isolate(input$type) == "B") { # Isolate the reactive expression from input$type
a = quantile(v$data$y, a/100, type = 7)
ggplot() +
geom_point(data = filter(v$data, y>a), aes(x = n, y = y), shape = 17, color = "firebrick1", size =4 ) +
geom_point(data = filter(v$data, y<=a), aes(x = n, y = y), shape = 16, color = "darkolivegreen4", size = 4) +
geom_abline(slope=0,intercept=a)
}
Upvotes: 2