【问题标题】:Shiny reactive objects logic issue闪亮的反应对象逻辑问题
【发布时间】:2021-01-12 13:24:38
【问题描述】:

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

我无法找到一种方法来使用反应性对象同时满足这两个约束:

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

下面是一个简化的代码(没有数据,没有加载/写入),它显示了我当前的尝试。 In this version the issue is that when a new problem is selected, the selected answer from the previous problem is immediately written.


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)

【问题讨论】:

  • 在自己构建一切之前,也许learnr 适合您?
  • @starja 感谢您的精彩提示,我不认识学习者,确实,这种任务看起来更方便。

标签: r shiny reactive


【解决方案1】:

这可能具有您正在寻找的功能。我做了一个可行的例子来尝试基于你所拥有的一些东西。

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

当通过numericInput 选择新问题时,radioButtons 将根据该问题的当前答案进行更新(使用rv$lst)。 Likewise, when a new answer is chosen (or answer is changed), the rv$lst will be updated with the new answer for storage.

我还添加了输出 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)

【讨论】:

    猜你喜欢
    • 2016-08-16
    • 2021-12-13
    • 2015-09-23
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    • 2013-07-16
    • 2021-08-07
    • 2017-07-03
    相关资源
    最近更新 更多