我正在构建一个Shiny应用程序,它根据selectInput()值更新checkboxGroupInput()。我还想存储选择/取消选择的值,以便每当我重新选择输入值时它们将显示为相同。为此,我使用反应值来存储选择。
这是一个玩具示例:
library(shiny)
letters = c('A','B','C','D','E','F','G','H','I','J','K','L')
words = list( "A" = c("apples","aardvark","alabama"),
"B" = c("banana","baltimore","beehive"),
"C" = c("catastrophe","cantalope"),
"D" = c("dinosaur","dairy","dolphin"),
"E" = c("eager","elephant","ecumenical"),
"F" = c("fleming","florida","flight"),
"G" = c("gator","greater","gait"),
"H" = c("HI"),
"I" = c("igloo","ignominious","interesting"),
"J" = c("jogging","jumpsuit"),
"K" = c("kellog","kangaroo"),
"L" = c("lemon","lime","lemonjello"))
ui <- fluidPage(
selectInput("letter","Choose Letter",choices=letters,selectize=F),
# Initiate check box group
checkboxGroupInput('words_by_letter',label='Select Your Favorite Words',choices = c(1))
)
server <- function(input, output, session) {
v_selected <- reactiveValues(
"A" = c("apples","aardvark","alabama"),
"B" = c("banana","baltimore","beehive"),
"C" = c("catastrophe","cantalope"),
"D" = c("dinosaur","dairy","dolphin"),
"E" = c("eager","elephant","ecumenical"),
"F" = c("fleming","florida","flight"),
"G" = c("gator","greater","gait"),
"H" = c("HI"),
"I" = c("igloo","ignominious","interesting"),
"J" = c("jogging","jumpsuit"),
"K" = c("kellog","kangaroo"),
"L" = c("lemon","lime","lemonjello"))
observeEvent(input$letter,{
updateCheckboxGroupInput(session,
inputId = "words_by_letter",
choices = words[[input$letter]],
selected = v_selected[[input$letter]])
})
observeEvent(input$words_by_letter,{
v_selected[[input$letter]] = input$words_by_letter
})
}
shinyApp(ui = ui, server = server)
在大多数情况下,这很好用。但是,如果您快速滚动输入(通过按住箭头按钮),最终将取消选中某些复选框组。我假设这与反应速度和与Javascript的沟通有关,但我不知道如何解决它。
注意:我也尝试为每个'字母'使用单独的conditionalPanel,但这会大大增加我的应用程序的加载时间,所以我不想使用该策略。 / p>
答案 0 :(得分:2)
这似乎是竞争条件,input$letter
的更新速度太快,以至于shinyServer无法跟上并尝试使用不一致的数据更新反应状态。例如,它使用“J”选项来修改和覆盖“I”字,然后输入选择器不再起作用。我不认为根本原因很容易解决。
但是,解决方法是仅在input$letter
和input$words_by_letter
中的值保持一致时才更新您的被动状态。
根据您的实际数据,这可能会或可能不会起作用 - 您需要组织数据,以便存在可以测试的一致性条件,并使用它来保护您的更新。在你的玩具示例中,我可以将选择的单词与初始化选择的单词进行比较 - 我利用了它。
我本可以比较匹配input$words_by_letter
的{{1}}中单词的第一个字母,但这看起来太专业了 - 这样,将所选数据与选择初始化进行比较更有可能推广。
以下是代码:
input$letter
对于它的价值,这就是应用程序的样子: