Я написал приложение Shiny R. Я пытаюсь показать первую строку таблицы. Это работает, когда я загружаю файл Excel или CSV, однако, когда я загружаю файл SAS7BDAT или XPT, я получаю сообщение об ошибке: argument is of length zero
. Этот обмен стека Ответ предполагает, что мне нужно проверить NULL и NA. Я также пытался это сделать, тестируя qctable
для обоих условий, но все равно получаю сообщение об ошибке. Интересно, если я загружаю файл CSV или Excel, а затем загружаю файл SAS (любой), он работает правильно.
Соответствующий код:
#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)