R闪亮:如何在一个reactiveValues对象中更改值。

时间:2022-02-12 14:27:37

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.

我正在开发一些有各种输入的闪亮应用程序。通常,我有一个设置,我希望用户按下一个按钮来接受输入值,然后它将创建需要设置的对象。当用户按下动画sliderInput对象上的播放按钮时,就应该进行模拟。已经创建的对象将在每次迭代中更新。

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.

一个问题是其中一个对象是reactiveValues列表。每当用户更改设置并单击“Accept”并运行它们时,我希望重新创建整个对象集(删除前面的值)。相反,reactiveValues列表中的对象并没有被覆盖,而是在每次使用下一个设置时进行扩充。所以每个对象槽实际上包含几个对象。

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.

要看到这一点,请尝试将最大迭代设置为一个值,单击accept,然后更改该值并再次接受,然后单击play。您将看到它将打印出reactiveValues对象的不同长度。

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.

我尝试了一些东西,比如rm(),试图删除重新激活的值。我也在这里尝试了解决方案(闪亮的:如何更新reactiveValues对象?),但它也不起作用。

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))

   })
 }) 
}
)
)

1 个解决方案

#1


2  

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:

收益率:

R闪亮:如何在一个reactiveValues对象中更改值。

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.

在上面我设置为20,运行它,然后设置为6,然后再次运行它。你可以看到它不再重复这些值,在它交替变成20和6之前。

The changes I made were:

我所做的改变是:

  • initialized param$tmp outside the loop
  • 在循环外部初始化param$tmp
  • removed the nesting of the observeEvent calls.
  • 删除了observeEvent调用的嵌套。

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.

我认为你应该在输入$run的情况下使用eventReactive,但是我不确定你要做什么,所以我就这么做。

#1


2  

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:

收益率:

R闪亮:如何在一个reactiveValues对象中更改值。

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.

在上面我设置为20,运行它,然后设置为6,然后再次运行它。你可以看到它不再重复这些值,在它交替变成20和6之前。

The changes I made were:

我所做的改变是:

  • initialized param$tmp outside the loop
  • 在循环外部初始化param$tmp
  • removed the nesting of the observeEvent calls.
  • 删除了observeEvent调用的嵌套。

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.

我认为你应该在输入$run的情况下使用eventReactive,但是我不确定你要做什么,所以我就这么做。