req()的意外行为

时间:2017-10-09 15:02:41

标签: r shiny

我遇到了R闪亮代码的意外行为,我问自己这是不是错误,或者我不明白req()是如何工作的。

我有一个应用程序,用户首先上传一个* .txt文件,其中包含带有位置ID,日期和其他数据的数据。然后用户必须选择两个数值。在col日期检查数据的NA。如果没有NA,则应显示文本,告诉用户一切正常。

以下是我的代码的两个版本。在output$txt <- renderText({中,我使用req()来测试是否已设置所有输入并加载文件。

两个代码之间的差异是req中最后两个参数的排序。而在第一个版本中,即使文件未上传,当两个数字输入都已设置时,绿色文本已经出现,第二个代码的行为与预期的一样;用户必须选择数值,并且必须在带有文本的绿色条之前选择一个文件。

为什么req()中的参数排序有所不同?

代码1:

library(shiny)
library(lubridate)

# UI 
ui <- fluidPage(
  fluidRow(
    column(4,
      wellPanel(

        fileInput("file1", label = h4("file upload")),  
        numericInput("in1", label = h4("first input"),value = 2.5, step=0.5),
        numericInput("in2", label = h4("second input"),value = NULL, step=0.5)
      )
    ),
    column(8, 

       h4(textOutput("txt"), tags$style(type="text/css", "#txt {vertical-align:top;align:center;color:#000000;background-color: #4cdc4c;}")),
       h2(""),
       textOutput("fileinfo"),
       tableOutput("tab_data")
    )
  )
)

# SERVER 
server <- function(input, output) {

  output$txt <- renderText({

    req(input$in1, input$in2, fl_data(), input$file1)

    "your data is ok and you have chosen input 1 and 2"
  })

  fl_data <- reactive({
    validate(
      need(input$file1 != "", "upload data and choose input 1 and 2...") 
    )

    inFile <- input$file1
    if (is.null(inFile)) {
      return(NULL)
    } else {
      dd <- read.table(inFile$datapath, sep=";", stringsAsFactors=FALSE, header=TRUE)
      dd[,2] <- ymd(dd[,2])
      if (sum(is.na(dd[,2]))>0) dd <- NULL
    }

  })

  output$tab_data <- renderTable({head(fl_data()[,1:4])})

  output$fileinfo <- renderPrint({input$file1})

}

# Run the application 
shinyApp(ui = ui, server = server)

代码2:

library(shiny)
library(lubridate)

# UI 
ui <- fluidPage(
  fluidRow(
    column(4,
      wellPanel(

        fileInput("file1", label = h4("file upload")),  
        numericInput("in1", label = h4("first input"),value = 2.5, step=0.5),
        numericInput("in2", label = h4("second input"),value = NULL, step=0.5)
      )
    ),
    column(8, 

       h4(textOutput("txt"), tags$style(type="text/css", "#txt {vertical-align:top;align:center;color:#000000;background-color: #4cdc4c;}")),
       h2(""),
       textOutput("fileinfo"),
       tableOutput("tab_data")
    )
  )
)

# SERVER 
server <- function(input, output) {

  output$txt <- renderText({

    req(input$in1, input$in2, input$file1, fl_data())

    "your data is ok and you have chosen input 1 and 2"
  })

  fl_data <- reactive({
    validate(
      need(input$file1 != "", "upload data and choose input 1 and 2...") 
    )

    inFile <- input$file1
    if (is.null(inFile)) {
      return(NULL)
    } else {
      dd <- read.table(inFile$datapath, sep=";", stringsAsFactors=FALSE, header=TRUE)
      dd[,2] <- ymd(dd[,2])
      if (sum(is.na(dd[,2]))>0) dd <- NULL
    }

  })

  output$tab_data <- renderTable({head(fl_data()[,1:4])})

  output$fileinfo <- renderPrint({input$file1})

}

# Run the application 
shinyApp(ui = ui, server = server)

1 个答案:

答案 0 :(得分:0)

req短路,就像&&||运营商一样。一旦遇到不可用的值(args从左到右评估),它就会停止反应链并且不关心任何进一步的args。

在第二个示例中,input$file1阻止fl_data()如果丢失则执行,因此fl_data中的验证永远不会发生。但是,与第一个示例中的req args一样,我只是删除input$file1output$txt的检查,因为它已经在fl_data中进行了检查。