我写了一个闪亮的申请表。我想展示桌子的第一行。当我上传一个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)