shinyvalidate - 在 add_rule() 中使用反应式表达式

shinyvalidate - using a reactive expression witin add_rule()

我正在尝试使用 shinyvalidate 包为我正在开发的应用程序实现用户反馈。我想传达给用户的一些反馈是他们选择的值是否在特定范围内。感兴趣的范围取决于他们所做的另一个输入(我已经包含了代码的简化 repex)。

因此,是否满足感兴趣的前提条件取决于反应值。我首先定义一个函数来检查提供的值是否在指定范围内。然后我在 add_rule() 中调用这个函数,使用一个反应作为函数的参数。这会导致错误,表明我无法使用 add_rule 访问反应式。据说是这种情况,因为 InputValidator 对象不是反应性消费者。

错误信息:

Warning: Error in Can't access reactive value 'num1' outside of reactive consumer.
i Do you need to wrap inside reactive() or observer()?
  55: <Anonymous>
Error: Can't access reactive value 'num1' outside of reactive consumer.
i Do you need to wrap inside reactive() or observer()?

但是,如果我在 add_rule() 中使用未命名的函数,我可以指定一个取决于反应的范围,并且我不再收到错误消息。我使用的未命名函数和命名函数是相同的,我不明白为什么我使用命名函数时会收到错误消息,但使用命名函数时却不会收到错误消息。

这是我使用命名函数的代码:

library(shiny)
library(shinyvalidate)
checkRange <- function(value, value2){
  if(value < -2 * value2 || value > 2 * value2 ){
    paste0("Please specify a number that is within the range: ", -2 * value2, ":", 2 * value2, " - Tank you!")
  }
}

ui <- fluidPage(
  fluidRow(
           numericInput("num1",
                        "Please specify your first number",
                        value = NULL),
           numericInput("num2",
                        "Please specify a different number",
                        value = NULL),
           verbatimTextOutput("selectedNums")
  
)
)

server <- function(input, output, session){
  iv <- InputValidator$new()
  iv$add_rule("num1", sv_required())
  iv$add_rule("num2", sv_required())
  iv$add_rule("num2", checkRange, value2 = input$num1)
  iv$enable()
  output$selectedNums <- renderPrint({
    req(iv$is_valid())
    paste0("The first number = ", input$num1, " and the second number = ", input$num2)
  })
}

app <- shinyApp(ui, server)

runApp(app)

这里是使用匿名函数的代码(UI 和服务器代码除了对 iv$add_rule() 的一次调用外大部分相同):

library(shiny)
library(shinyvalidate)
ui <- fluidPage(
  fluidRow(
           numericInput("num1",
                        "Please specify your first number",
                        value = NULL),
           numericInput("num2",
                        "Please specify a different number",
                        value = NULL),
           verbatimTextOutput("selectedNums")
  
)
)

server <- function(input, output, session){
  iv <- InputValidator$new()
  iv$add_rule("num1", sv_required())
  iv$add_rule("num2", sv_required())
  iv$add_rule("num2", function(value){
    if(value < - 2 * input$num1 || value > 2 * input$num2){
      paste0("Please specify a number that is within the range: ", -2 * input$num1, ":", 2 * input$num1, " - Tank you!")
    }
  })
  iv$enable()
  output$selectedNums <- renderPrint({
    req(iv$is_valid())
    paste0("The first number = ", input$num1, " and the second number = ", input$num2)
  })
}

app <- shinyApp(ui, server)

runApp(app)

我更喜欢使用命名函数,因为我想多次重用代码。谁能帮我解决为什么我收到带有命名函数的错误消息,但没有收到未命名函数的错误消息?

你可以这样做:

  iv$add_rule("num2", function(value){checkRange(value, input$num1)})