【问题标题】:query and manipulation of variables in shiny server查询和操作闪亮服务器中的变量
【发布时间】:2021-01-02 17:41:41
【问题描述】:

我将继续尝试了解闪亮的基础知识。我现在尝试通过文本框 (input$answer) 获取用户输入,基于该输入 (input$answer == "xyz") 进行条件测试,并根据此条件生成输出 (if { <do stuff for correct answer> } else { <do stuff for incorrect answer> })。

我想我已经掌握了很多基础知识。我可以获得用户输入,我已将其转换为反应值,因此我可以在 if 语句中生成查询而不会出错。我可以在提交答案后使用该用户输入生成输出。

不过有两个问题:

  1. 查询(isolate(input$answer) == "Hello") 永远不会为TRUE,因为isolare(input$answer) 的值始终保持它最初分配的值。在当前情况下是“输入文本...”,但如果我将其留空,则行为不会改变(它只是假设“”作为值)。如果我将语句更改为if (isolate(input$answer) == "Enter text..."),则评估将始终为 TRUE。为什么即使在随后的paste0("Your answer of ",input$answer, " is incorrect!") }) 中该值已正确更新,该值也不会改变?
  2. 有没有办法在服务器启动时防止正确/不正确的评估,只有在第一次点击提交按钮时才踢它?
library(shiny)

#// Define UI for game ----
ui <- fluidPage(

     #// for query
     fluidRow ( 
     
          #// column width and title
          column(6, h3("Question"),
                 
               h4("Type the word `Hello`"),  
     
               #// Input: Text Box
               textInput("answer", h3("Text input"),
                          value = "Enter text..."),
     
               #// submit button to terminate the text input
               submitButton("Submit")
          
          ), #// end column
     
          #// column width and title
          column(6, h3("Evaluation"),

               #// Output: Text ----
               textOutput(outputId = "evaluation")  
          
          ) #// end column
      ) #// end fluidrow
) # end fluidpage

# Define server logic ----
server <- function(input, output) { 

     #// set up variables
     answer <- reactiveValues()

     #// logic for correct vs. incorrect
     if (isolate(input$answer) == "Hello") {
          #// correct counter up by one
          correct <- correct + 1
          counter <- counter + 1
          #// answer is correct
          output$evaluation <- renderText({ 
          paste0("Your answer of `",input$answer, "` is correct!") }) 
     } #// end if
     else {
          #// answer is not correct
          output$evaluation <- renderText({ 
          paste0("Your answer of `",input$answer, "` is incorrect!") }) 
          counter <- counter + 1
     } #// end else     

     #// stop app if count reaches number of games
     if (counter == num) stopApp()
     
} #// end server

# Run the app ----

counter <- 0
num <- 10
shinyApp(ui = ui, server = server)

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    您的主要问题是您试图对反应上下文之外的值执行逻辑比较。在您比较的环境中,input$answer 从未改变。

    另外,answer &lt;- reactiveValues() 什么也不做,因为您从未访问过 answer

    这是reactiveValuesobserveEvent 的方法:

    library(shiny)
    #// Define UI for game ----
    ui <- fluidPage(
      #// for query
      fluidRow ( 
        #// column width and title
        column(6, h3("Question"),
               h4("Type the word `Hello`"),  
               #// Input: Text Box
               textInput("answer", h3("Text input"),
                         placeholder = "Enter text..."),
               #// submit button to terminate the text input
               submitButton("Submit")
        ), #// end column
        #// column width and title
        column(6, h3("Evaluation"),
               #// Output: Text ----
               textOutput(outputId = "evaluation"),
               br(),
               textOutput(outputId = "trials")  
        ) #// end column
      ) #// end fluidrow
    ) # end fluidpage
    
    # Define server logic ----
    server <- function(input, output) { 
    #// set up variables
      values <- reactiveValues()
      values$counter <- -1
      values$correct <- 0
      num <- 10
      
      #// logic for correct vs. incorrect
      observeEvent(input$answer,{
        if (isolate(input$answer) == "Hello") {
        #// correct counter up by one
        values$correct <- values$correct + 1
        #// answer is correct
        output$evaluation <- renderText({ 
          paste0("Your answer of `",input$answer, "` is correct!") }) 
      } #// end if
      else {
        #// answer is not correct
        output$evaluation <- renderText({ 
          paste0("Your answer of `",input$answer, "` is incorrect!") }) 
      } #// end else     
      values$counter <- values$counter + 1  
      output$trials <- renderText({paste0("Trials: ",values$counter,"  Correct: ",values$correct)})  
      #// stop app if count reaches number of games
      if (values$counter >= num) stopApp()
      })
    } #// end server
    # Run the app ----
    shinyApp(ui = ui, server = server)
    

    【讨论】:

    • 太棒了。谢谢你。我想我现在看到了如何定义变量并使用它们。如果变量仅在服务器端使用,它们可以照常使用。如果它们需要在 UI 和服务器之间穿梭,则必须将它们定义为响应式,然后可以通过闪亮命令中的 name$xyz 调用来处理它们。如果要在其他函数中使用它们(例如 if),则需要使用隔离来调用它们。最后,将所有内容包装在`observeEvent(input$answer)`中,每次提交新答案时,整个位只会执行一次。
    【解决方案2】:

    当你从普通的 R 转到 Shiny 时,你需要稍微改变一下你的逻辑。您想要响应的所有内容(即响应用户输入的更改)都需要在响应上下文中(例如 renderText)。

    在此示例中,您的 if 语句实际上仅在应用程序加载时执行一次。要让它更符合您的要求,请尝试以下方式:

        output$evaluation <- renderText({ 
            
            if (input$answer == "Hello") {
                #// correct counter up by one
                correct <- correct + 1
                counter <- counter + 1
                paste0("Your answer of `",input$answer, "` is correct!") 
            } #// end if
            else {
                #// answer is not correct
                counter <- counter + 1
                paste0("Your answer of `",input$answer, "` is incorrect!") 
            } #// end else     
            
        })  
    

    在回答您的第二个问题时,我建议做两件事。首先是在您的文本输入定义中将value = "Enter text..." 更改为placeholder = "Enter text..."。这将使应用程序知道“输入文本”不是真正的答案。然后,您可以在 renderText 表达式的开头使用 req(input$answer) 来停止执行,除非实际填写了文本字段。

    【讨论】:

    • 谢谢! placeholder = "Enter text..." 完全符合我的想法。它解释了为什么在那里拥有“价值”会搞砸一切。
    猜你喜欢
    • 2017-01-15
    • 2016-05-23
    • 2016-10-26
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 2021-03-10
    • 2018-04-21
    • 2018-01-11
    相关资源
    最近更新 更多