代码之家  ›  专栏  ›  技术社区  ›  CT Hall

如何避免在用if else子句呈现表的第一行时出现闪亮的R错误“argument is of length zero”

  •  0
  • CT Hall  · 技术社区  · 7 年前

    我写了一个闪亮的申请表。我想展示桌子的第一行。当我上传一个Excel文件或CSV时,这是有效的,但是当我上传一个SAS7BDAT或XPT文件时,我得到错误: argument is of length zero . 这个堆栈交换 Answer 建议我需要测试零和NA。我也试过,测试 qctable 但我还是收到了错误。有趣的是,如果我上传一个CSV或Excel文件,然后再上传一个s a s文件(任何一个),它都能正常工作。

    相关代码:

    #outputs the first row of the input file.
      output$firstrow <- renderText({
        req(qctable())
        if (filext() %in% c('.csv', '.txt')) {
          return(head(read_lines(input$qcfile$datapath), 1))
        } else if (
          (filext() %in% c('.xpt', '.sas7bdat')) | # This line and the next seem to be the issue
          (filext() %in% c('.xls', '.xlsx') & input$headers == TRUE)
        ) {
          return(paste0(names(qctable())))
        } else if ((filext() %in% c('.xls', '.xlsx') & input$headers == FALSE)) {
          return(paste0(qctable()[1,]))
        } else {
          return('Invalid file type!')
        }
      })
    

    我可以通过将SAS文件条件和Excel文件条件作为不同的测试包含在 if 但这看起来很笨拙。

    就像这样:

      #outputs the first row of the input file.
      output$firstrow <- renderText({
        req(qctable())
        if (filext() %in% c('.csv', '.txt')) {
          return(head(read_lines(input$qcfile$datapath), 1))
        } else if (filext() %in% c('.xpt', '.sas7bdat')) {
          return(paste0(names(qctable()), collapse=('  ')))
        } else if (filext() %in% c('.xls', '.xlsx') & input$headers == TRUE) {
          return(paste0(names(qctable()), collapse=('  ')))
        } else if ((filext() %in% c('.xls', '.xlsx') & input$headers == FALSE)) {
          return(paste0(qctable()[1,], collapse=('  ')))
        } else {
          return('Invalid file type!')
        }
        })
    

    也许还需要注意的是,如果上载的文件类型无效,则会发生相同的错误,但如果先上载CSV/Excel,则会正常工作。

    完整代码:

    #### Libraries ####
    library(shiny)
    library(tidyverse)
    library(readxl)
    library(haven)
    
    #### UI ####
    ui <- fluidPage(
      # Sidebar with a slider input for number of bins 
      sidebarLayout(
        sidebarPanel(
          width = 3,
          # Input: Select a file 
          fileInput("qcfile", "Choose a File to QC",
                    multiple = FALSE,
                    accept = c("text/csv",
                               "text/comma-separated-values,text/plain",
                               ".csv",
                               '.txt',
                               '.xlsx',
                               '.xls',
                               '.xpt',
                               '.sas7bdat')),
          # Choose Separator
          htmlOutput('delimrb'),
          # Choose header values
          htmlOutput('header'),
          # Choose column TDxs are stored
          tags$strong('File Extension:'),
          verbatimTextOutput('file_ext')
        ),
        # Creates Main Panel with relevant tabs 
        mainPanel(width = 9,
          tabsetPanel(
            type = 'tabs',
            tabPanel('1st Row', verbatimTextOutput('firstrow'))
          ))
      )
    )
    
    #### Server #### 
    server <- function(input, output) {
      #determines input file extention
      filext <- reactive({
        req(input$qcfile)
        fext <- tolower(str_extract(as.vector(input$qcfile$datapath), '\\.[^.]+$'))
        return(fext)
      })
    
      output$file_ext <- renderText(filext())
    
      # Sets UI for delimiter if input file is .csv or .txt
      output$delimrb <- renderUI({
        req(input$qcfile)
        if (filext() %in% c('.csv', '.txt')) {
          radioButtons("delimiter", "Delimiter for CSV/TXT",
                       choices = c(comma = ',',
                                   pipe = '|',
                                   tab = '\t')
          )
        }
      })
    
      # Sets UI for header if input file is not sas/xpt
      output$header <- renderUI({
        req(input$qcfile)
        if (filext() %in% c('.csv', '.txt', '.xlsx', '.xls')) {
          radioButtons('headers', 'Header row present?',
                       choices = c('Yes' = TRUE,
                                   'No' = FALSE))
        }
      })
    
      #outputs the first row of the input file.
      output$firstrow <- renderText({
        req(qctable())
        if (filext() %in% c('.csv', '.txt')) {
          return(head(read_lines(input$qcfile$datapath), 1))
        } else if (
          (filext() %in% c('.xpt', '.sas7bdat')) | # This line and the next seem to be the issue
          (filext() %in% c('.xls', '.xlsx') & input$headers == TRUE)
        ) {
          return(paste0(names(qctable())))
        } else if ((filext() %in% c('.xls', '.xlsx') & input$headers == FALSE)) {
          return(paste0(qctable()[1,]))
        } else {
          return('Invalid file type!')
        }
      })
    
      # Creates Table from input file
      qctable <- reactive({
        req(input$qcfile)
        if (filext() %in% c('.csv', '.txt')){
          return(read_delim(file = input$qcfile$datapath,
                            delim = input$delimiter,
                            col_names = as.logical(input$headers),
                            col_types = cols(.default = 'c'))
          )
        } else if (filext() %in% c('.xls', '.xlsx')) {
          return(read_excel(path = input$qcfile$datapath,
                            col_names = as.logical(input$headers),
                            col_types = 'text'))
        } else if (filext() %in% c('.xpt')) {
          return(read_xpt(file = input$qcfile$datapath))
        } else if (filext() %in% c('.sas7bdat')){
          return(read_sas(data_file = input$qcfile$datapath))
        }
      })
    
    }
    
    #### Run the application ####
    shinyApp(ui = ui, server = server)
    
    0 回复  |  直到 7 年前
    推荐文章