I am developing some shiny apps with various inputs. In general, I have a setup where I want the user to push a button to accept the input values, which will then create objects that need to be set up. The a simulation should run when the user presses the play button on a animated sliderInput object. The objects that have been created will be updated at each iteration.
One problem is that one of the objects is a reactiveValues list. I would like the whole set of objects to be recreated (erasing earlier values) whenever a user changes a setting and clicks "Accept" and runs them. Instead, the objects in the reactiveValues list are not being overwritten but are being augmented each time with the next settings. So each object slot actually holds several objects.
To see this, try setting the maximum iteration to a value, hit accept, then change the value and accept again, then click play. You will see it will print out different lengths of the reactiveValues object.
I tried a few things like rm() to try to delete the reactiveValues. Also I tried the solution here (shiny: How to update a reactiveValues object?) but it didn't work either.
library(shiny)
iter_test <- shinyApp(
ui=shinyUI(fluidPage(
titlePanel("title panel"),
sidebarLayout(position = "left",
sidebarPanel("Simulation parameters",
sliderInput("iter","Progress of simulation",value=1, min=1, max=30, round=TRUE, step=1,
animate=animationOptions(interval=1, loop=FALSE)),
actionButton('run',"Accept settings, press play above"),
sliderInput('max_iter','Maximum number of iterations',value=20, min=1, max=30, round=TRUE, step=1)
),
mainPanel( plotOutput("plots"))
)#end of layout
)
)#end of UI definition
,
server=shinyServer(function(input, output, session)
{
observeEvent( input$run, {
#only set up simulation objects if accept is clicked
updateSliderInput(session, "iter", label="Progress of simulation", value=1, min=1, max=input$max_iter, step=1)
#try(rm(params))
#set up objects needed for simulation
params <- reactiveValues(tmp=rep(1, input$max_iter))
#when the play button is pressed, the following loop should trigger.
observeEvent( input$iter, {
print(length(params$tmp))
})
})
}
)
)
I think this gets you what you want:
library(shiny)
iter_test <- shinyApp(
ui=shinyUI(fluidPage(
titlePanel("title panel"),
sidebarLayout(position = "left",
sidebarPanel("Simulation parameters",
sliderInput("iter","Progress of simulation",value=1, min=1, max=30, round=TRUE, step=1,
animate=animationOptions(interval=1, loop=FALSE)),
actionButton('run',"Accept settings, press play above"),
sliderInput('max_iter','Maximum number of iterations',value=20, min=1, max=30, round=TRUE, step=1)
),
mainPanel( plotOutput("plots"))
)#end of layout
)),#end of UI definition
server=shinyServer(function(input, output, session)
{
params <- reactiveValues(tmp=NULL)
observeEvent( input$run, {
req(input$run)
updateSliderInput(session, "iter", label="Progress of simulation", value=1, min=1, max=input$max_iter, step=1)
#try(rm(params))
#set up objects needed for simulation
params$tmp =rep(1, input$max_iter)
})
#when the play button is pressed, the following loop should trigger.
observeEvent( input$iter, {
req(input$iter)
print(length(params$tmp))
})
})
)
Yielding this:
In the above I set to 20, ran it, then set to 6, and ran it again. You can see it is no longer repeating the values, before it would have alternated 20 and 6.
The changes I made were:
param$tmp
outside the loopobserveEvent
calls. I kind of think you should be using an eventReactive
here for the input$run
case, but I am not really sure where you are going with this, so I let it be.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With