闪亮的反应对象逻辑问题

时间:2020-09-26 11:29:43

标签: r shiny reactive

我的目标是实现一个Shiny应用程序,该应用程序向用户显示一些“问题”并列出可能的答案,然后让用户选择答案并将其存储。每个问题都有一个预先存储的答案,用户可以覆盖。

我找不到使用反应性对象同时满足这两个约束的方法:

  • 让用户选择下一个问题,并从先前存储的答案中重新初始化答案
  • 当用户选择新答案时(仅在这种情况下)存储当前问题的答案

下面是显示我当前尝试的简化代码(无数据,无装载/写入)。在这个版本中的问题是,当选择一个新的问题,从以前的问题选择的答案被立即写入。


library(shiny)

maxProblem=10

ui <- fluidPage(
  
  titlePanel("Debugging test"),
  fluidRow(
    column(12,
           verbatimTextOutput("nbProblems"),
           uiOutput("ProblemSelection"),
           uiOutput("answerSelection")
    )
  )
)



server <- function(input, output) {
  
  

  output$ProblemSelection <- renderUI({
    numericInput("ProblemSelectionNo", 
                 "Select Problem no", 
                 value = 1, min=1, max=maxProblem)
  })
  
  
  currentProblemData <- reactive({
    print("calling loadCurrentProblemData")
    if (!is.null(input$ProblemSelectionNo)) {
      print("pretending to load data and previously stored answer for problem", input$ProblemSelectionNo)
      list( choices=c(1,2,3), answer=1)
    }
  })

    output$answerSelection <- renderUI({
    l<-currentProblemData()
    choicesList <- l$choices
    names(choicesList) <- l$choices
    radioButtons("answerInput", label = "Select answer",
                 choices = choicesList, 
                 selected = l$answer)
  })
  

  writeChanges <- observe({
    print('calling writeChanges')
    l<-currentProblemData()
    newAnswer <- input$answerInput
    prevAnswer <- l$answer
    if (!is.null(prevAnswer) && !is.null(newAnswer) && (newAnswer != prevAnswer)) {
      print(paste('Pretending to write new answer :',newAnswer,'for problem', input$ProblemSelectionNo))
      l$answer <- newAnswer
    }

  })

  
}

# Run the application 
shinyApp(ui = ui, server = server)

1 个答案:

答案 0 :(得分:2)

这可能具有您要寻找的功能。我做了一个可行的例子,根据您的一些经验进行尝试。

首先,我创建了一个默认列表choices_answer,该列表可以灵活地存储您的默认问题选择和答案。 reactiveValues列表lstrv$lst)将从此开始,然后随着选择新答案以存储新答案而更改。

通过numericInput选择了新问题后,radioButtons会根据该问题的当前答案进行更新(使用rv$lst)。同样地,当选择了新的答案(或答案被改变)时,rv$lst将被与存储的新的答案更新。

我还添加了输出ListData,以显示您使用单选按钮进行选择时答案的存储方式。

library(shiny)

maxProblem = 5

choices_answer = list()
for (i in seq_along(1:maxProblem)) {
  choices_answer[[i]] <- list(
    choices = c("1", "2", "3"),
    answer = "1"
  )
}

ui <- fluidPage(
  titlePanel("Debugging test"),
  fluidRow(
    column(12,
           numericInput("ProblemSelectionNo", 
                        "Select Problem no", 
                        value = 1, min = 1, max = maxProblem),
           radioButtons("answerInput", label = "Select answer",
                        choices = choices_answer[[1]][["choices"]]),
           verbatimTextOutput("ListData")
    )
  )
)

server <- function(input, output, session) {
  
  rv <- reactiveValues(lst = choices_answer)
  
  observeEvent(input$ProblemSelectionNo, {
    updateRadioButtons(session, "answerInput", 
                       choices = rv$lst[[input$ProblemSelectionNo]][["choices"]], 
                       selected = rv$lst[[input$ProblemSelectionNo]][["answer"]])
  })
  
  observeEvent(input$answerInput, {
    rv$lst[[input$ProblemSelectionNo]][["answer"]] <- input$answerInput
  })
  
  output$ListData <- renderPrint({rv$lst})
  
}

# Run the application 
shinyApp(ui = ui, server = server)