在 Shiny 中,req() 和 if() 语句有什么区别?

Dav*_*era 2 r shiny shiny-reactivity

假设我有以下用户界面:

ui <- fluidPage(
checkboxGroupInput("checkbox", "", choices = colnames(mtcars)),
tableOutput("table")
)
Run Code Online (Sandbox Code Playgroud)

我想渲染一个表格,mtcars其中至少选择了一个复选框选项。为此,我遇到了req(),但我看不出它与if语句有什么不同,即使阅读有关此函数的文档,它的定义也非常接近if语句的作用:

在进行计算或操作之前,请确保值可用(“真实”-请参阅详细信息)。如果任何给定的值不真实,则通过引发“静默”异常(Shiny 未记录,也不显示在 Shiny 应用程序的 UI 中)来停止操作。

那么,这个表格是如何呈现的:

server <- function(input, output) {

    output$table <- renderTable({
    req(input$checkbox)
    mtcars %>% select(input$checkbox)
    })
}

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

和这个不一样?:

server <- function(input, output) {

    output$table <- renderTable({
    if(!is.null(input$checkbox))
    mtcars %>% select(input$checkbox)
    })
}

shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)

TL;DR:除了你如何写之外,它req()if陈述有什么不同?

MrF*_*ick 5

好吧,您可以req通过键入不带括号的名称来查看代码。

function (..., cancelOutput = FALSE) 
{
    dotloop(function(item) {
        if (!isTruthy(item)) {
            if (isTRUE(cancelOutput)) {
                cancelOutput()
            }
            else {
                reactiveStop(class = "validation")
            }
        }
    }, ...)
    if (!missing(..1)) 
        ..1
    else invisible()
}
Run Code Online (Sandbox Code Playgroud)

基本上发生的事情是它遍历您传入的所有值并检查它们是否看起来“真实”,而不仅仅是检查 null。如果是这样,它将取消输出。而if语句只会有条件地执行一段代码,不一定会取消输出。例如,当你有这个块时

server <- function(input, output) {
    output$table <- renderTable({
      if(!is.null(input$checkbox)) 
         mtcars %>% select(input$checkbox)
      print("ran")
    })
}
Run Code Online (Sandbox Code Playgroud)

if表达式中的代码是有条件地运行的,但是print()After 仍然总是运行,因为它不在if块中。但是用一个req

server <- function(input, output) {
    output$table <- renderTable({
      req(input$checkbox)
      mtcars %>% select(input$checkbox)
      print("ran")
    })
}
Run Code Online (Sandbox Code Playgroud)

req()基本中止块的其余部分,因此print(),如果不运行req是不是“truthy”值。它只是更容易防止不必要的代码运行。