2017-02-12 340 views
3

我開發與各種輸入一些閃亮的應用程序。一般來說,我有一個設置,我希望用戶按下按鈕來接受輸入值,然後創建需要設置的對象。當用戶按動畫sliderInput對象上的播放按鈕時,應該運行模擬。已創建的對象將在每次迭代中更新。[R閃亮:如何改變在reactiveValues值對象

一個問題是對象之一是reactiveValues列表。我希望每當用戶更改設置並單擊「接受」並運行它們時,都會重新創建整個對象集(擦除較早的值)。相反,reactiveValues列表中的對象不會被覆蓋,而是會隨着下一個設置每次增加。所以每個對象槽實際上都包含多個對象。

看到這一點,試圖最大迭代設定的值,命中接受,然後更改值,然後再次接受,然後點擊播放。你會看到它會打印出不同長度的reactiveValues對象。

我嘗試了一些東西像RM()來嘗試刪除該reactiveValues。我也試過這裏的解決方案(shiny: How to update a reactiveValues object?),但它也沒有工作。

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

    }) 
}) 
} 
) 
) 
+0

我覺得我得到的東西,你可以工作,但不能完全確定,因爲我真的不知道你在哪裏與此打算。 –

回答

2

我覺得這得到你想要的東西:

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

屈服這樣的:

enter image description here

在我設置爲20以上,運行它,然後設置爲6 ,並再次運行它。你可以看到它不再是重複的值,它會交替20和6

我所做的更改之前爲:

  • 初始化param$tmp外循環
  • 刪除observeEvent的嵌套調用。

我有點想你應該在這裏使用eventReactiveinput$run情況,但我真的不知道你在哪裏與此打算,所以我順其自然。

+0

嗨邁克感謝您的意見。我想你是對的,通過在像我這樣的觀察事件中使用params,每次我點擊跑步時都會運行,這不是我所期望的。我預計這些對象每次都會被覆蓋。爲了回答你的問題,我嘗試用eventReactive替換第一個observeEvent,但它不起作用,因爲它沒有在params中設置值。我相信observeEvent用於執行一系列響應被動值的動作,而eventReactive應該執行計算並返回一個值。 –

+0

另外我認爲在第二個observeEvent的開頭添加req(input $ run)解決了這個問題,因爲如果你還沒有初始化任何東西,(inpu $ run),我不希望任何結果圖或運行迭代的輸出。 –

+0

好的。這是一個可以接受的答案嗎? –