我開發了一個Shiny應用程序,允許用戶有條件地選擇一些相關事件。下面是一個非常簡單的玩具示例,以幫助說明我的問題。用於多個相關事件的一個動作按鈕閃亮
在我真正的問題中,服務器代碼包含多個計算上昂貴的程序,可以運行。有一個「基線」函數必須運行以產生輸出,然後firstObject或secondObject將其作爲輸入,並在用戶選擇輸出時產生更多輸出。
每個功能可能需要30到40分鐘的時間。所以,我編寫了代碼以允許用戶使用checkInputBox來選擇他們想要運行的函數,然後在選擇它們之後,有一個單獨的動作按鈕來運行它們,允許用戶離開並讓流程結束很長時間。這比每個可能的事件都有一個actionButton更方便。
下面的代碼在產生所有期望的輸出方面是成功的。但是,從設計的角度來看,我不確定它是否「正確」。在我的玩具例子中,代碼很簡單,但假設baseObject的代碼需要30分鐘才能運行。在baseObject運行時,firstObject和secondObject的代碼也被執行,因爲它們依賴於相同的操作按鈕。但是,在baseObject的函數完成之前,他們不能做任何事情。類似地,在firstObject完成之前,secondObject不能執行任何操作。
再一次,這一切工作,併產生正確的輸出(在我的真實代碼以及在玩具代碼中)。但是,是否有一種方法來維護單個動作按鈕,但是對於firstObject,如果用戶選擇它,則不會執行任何操作,直到基線Object生成其輸出,然後secondObject將等待firstObject輸出它的輸出。
我擔心的是,我在firstObject中創建額外的計算開銷,試圖做一些它不能做的事情,直到baseObject完成並且它一遍又一遍地循環,直到它可以正確執行爲止。
我知道我可以創建不同的動作按鈕。例如,我可以爲基線創建一個操作按鈕,然後用戶可以等待完成,然後單擊firstObject的操作按鈕等等。但是,從功能上來說,這不會起到真正的問題的作用,因爲它允許整個選定的進程運行,這可能需要幾個小時,用戶不需要在他們的機器前面。
謝謝,我希望這段代碼能幫助說明這個問題,正如我描述的那樣。
ui <- {
fluidPage(
h3('Run Stuff'),
checkboxInput("runModel1", "Model 1"),
checkboxInput("runModel2", "Model 2"),
actionButton('runAll', 'Run Models'),
verbatimTextOutput("out1"),
verbatimTextOutput("out2")
)
}
server <- function(input, output, session) {
baseObject <- eventReactive(input$runAll, {
if(input$runModel1){
runif(100)
}
})
firstObject <- eventReactive(input$runAll, {
if(input$runModel1){
runif(100) + baseObject()
}
})
secondObject <- eventReactive(input$runAll, {
if(input$runModel2){
runif(100) + firstObject()
}
})
output$out1 <- renderPrint({
if (input$runModel1)
firstObject()
})
output$out2 <- renderPrint({
if (input$runModel2)
secondObject()
})
} # end server
shinyApp(ui, server) #run