【问题标题】:Using a reactive expression in an if statement in shiny在闪亮的 if 语句中使用反应式表达式
【发布时间】:2016-04-21 15:07:43
【问题描述】:

我正在编写一个闪亮的应用程序,其输出应取决于在闪亮的反应式表达式中计算的变量的值。我相信我没有复制实际的应用程序,而是用以下简单的应用程序重现了我的问题:

ui.R file:

   library(shiny)

   shinyUI(pageWithSidebar(

   headerPanel("Illustrating problem"),

   sidebarPanel(

   numericInput('id1', 'Numeric input, labeled id1', 0, min = 0, max = 100, step        =5)

  ),

  mainPanel(

    h4('You entered'),

    verbatimTextOutput("oid1"),

    verbatimTextOutput("odic")

  )
))

server.R file


library(shiny)

shinyServer(

  function(input, output) {

    output$oid1 <- renderPrint({input$id1})

    x<-reactive({5*input$id1})

    if (x()>50) output$oid2<-renderPrint({"You entered a number greater than 10"})

    else output$oid2<-renderPrint({"You entered a number less than or equal to 
10"})

  }
)

如果我像这样运行它,那么我会收到错误: 错误 .getReactiveEnvironment()$currentContext() :`

在没有活跃的反应上下文的情况下不允许操作。 (你试过 做一些只能从反应式内部完成的事情 表达式或观察者。)

如果我将 if 语句更改为:if (x&gt;50) ... 那么我得到错误:

x > 50 中的错误:比较 (6) 仅适用于原子和列表类型

当我将 if 语句更改为:if (reactive({(x&gt;50)})) ... 然后我收到错误消息:

if (reactive({ : 参数不可解释为逻辑) 中的错误

非常感谢任何帮助

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    几个问题。第一个也是最大的问题是您似乎不了解反应性是如何工作的。错误说“没有活动的反应上下文不允许操作”,这就是问题所在 - 您正在服务器函数的主体内访问x(),但不在反应上下文中。例如,任何render* 函数都是反应式上下文。因此,要解决这个问题,您只需将 if 语句移动到 renderPrint 中即可。

    另一个小问题是您的输出 ID 不匹配(verbatimTextOutput("odic")output$oid2)。

    如果你不了解反应性,我强烈建议你花半个小时来更好地理解它。 This tutorial 有一个关于反应性的部分可能会有所帮助,或者您可以重新阅读 RStudio 的官方闪亮教程。

    这是您的固定应用的代码(我删除了一堆无用的 UI 元素)

    library(shiny)
    ui <- fluidPage(
      numericInput('id1', 'Numeric input, labeled id1', 0, min = 0, max = 100, step=5),
      verbatimTextOutput("oid1"),
      verbatimTextOutput("oid2")
    
    )
    server <- function(input, output, session) {
      output$oid1 <- renderPrint({input$id1})
    
      x<-reactive({5*input$id1})
    
      output$oid2<-renderPrint({
        if (x()>50) {
          "You entered a number greater than 10"
        } else {
          "You entered a number less than or equal to 10"
        }
      })
    }
    shinyApp(ui = ui, server = server)
    

    【讨论】:

      【解决方案2】:

      请注意,Shiny 根据事件驱动模型工作 - 几乎所有面向图形的 UI 都是如此(今天是绝大多数)。这不是一个新概念,至少从 80 年代就已经存在,但它比遵循单个流程图的编程要复杂得多——它确实需要一些时间来适应。

      无论如何,在闪亮的reactiveoutputobserve 语句必须在顶层,我认为这没有例外。

      你可能想要这样的东西:

      library(shiny)
      
      u <- shinyUI(pageWithSidebar(
      
        headerPanel("Illustrating problem"),
      
        sidebarPanel(
          numericInput('id1', 'Numeric input, labeled id1', 0, min = 0, max = 100, step =5)
        ),
      
        mainPanel(
      
          h4('You entered'),
          verbatimTextOutput("oid1"),
          verbatimTextOutput("oid2")
      
        )
      ))
      
      s <- shinyServer(function(input, output) {
      
          output$oid1 <- renderPrint({input$id1})
      
          x<-reactive({5*input$id1})
      
          output$oid2<-renderPrint({
            if (x()>50){
               "You entered a number greater than 10"
            } else {
               "You entered a number less than or equal to 10"
            }
          }
        )
      }
      )
      shinyApp(ui = u, server = s)
      

      产量:

      【讨论】:

      • 你也得到了一点,为了截图的努力......顺便说一句,我不认为这是鼓励的,但你当然可以将输出语句放在观察者/反应者中。但不应该。
      • 感谢您的解释。我的问题是,在我的实际应用程序中,我在 if else 语句中有一大堆命令,而且它不仅仅是一个 renderPrint 命令。关于如何做到这一点的任何想法?
      • 这对我也没有用,假设您只想在另一个反应变量具有特定值的情况下定义一个反应变量,那么您不能使用渲染环境并且必须在 main 中执行 if服务器主体
      • stackoverflow.com/questions/37710358/…。这是一个回答我的问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      相关资源
      最近更新 更多