Hello,
I try to make Shiny react to an uploaded file. Depending on the extension of the file (csv/txt or xlsx) specific ui elements should show up or hide. For this I loaded the package "assertthat", but I think I am using it wrong.
I am also new to error handling with validate and I am not sure if the error has something to do with that.
When I use the app, the error message appears on the "Tabelle" register:
"assert_that: length of assertion is not 1".
And while the error message of validate changes correctly, the ui elements I want to show up when a .txt file is uploaded, aren't getting rendered.
I call for the ui elements with a conditional panel:
conditionalPanel(condition = "output.dateiformat == 'csvtxt'",
And output.dateiformat ist generated when the file is put into a reactive data frame:
if (see_if(has_extension(infile$datapath, 'csv')) == TRUE
| see_if(has_extension(infile$datapath, 'txt')) == TRUE
| see_if(has_extension(infile$datapath, 'TXT')) == TRUE
| see_if(has_extension(infile$datapath, 'CSV')) == TRUE) {
output$dateiformat <- renderText('csvtxt')
outputOptions(output, "dateiformat", suspendWhenHidden = FALSE)
(see_if and has_extension are functions of the external package "assertthat" and I am not sure if I need it.)
Ideally my app would work without the help of the package "assertthat", but I could not find a way to return the extension of a file without additional input of the user.
All relevant parts of the code:
library(shiny)
library(xlsx)
library(readxl)
library(assertthat)
`%then%` <- shiny:::`%OR%`
ui <- fluidPage(
sidebarLayout(sidebarPanel(
fileInput("userDatei",
"Datei hochladen:",
multiple = FALSE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv",
'.xlsx'),
placeholder = "...",
buttonLabel = "Durchsuchen"),
conditionalPanel(condition = "output.dateiformat == 'csvtxt'",
radioButtons("dec", "Dezimalzeichen:",
choices = c("Komma" = ",",
"Punkt" = "."),
selected = "."),
radioButtons("sep", "Trennzeichhen:",
choices = c("Komma" = ",",
"Semikolon" = ";",
"Tab" = "\t"),
selected = ","),
radioButtons("quote", "Anführungszeichen:",
choices = c("Keine" = "",
"Doppelte" = '"',
"Einfache" = "'"),
selected = '"')
),
conditionalPanel(condition = "output.dateiformat == 'xlsx'", "")
),
mainPanel(
tabsetPanel(
tabPanel("Diagramm", fluidPage(plotOutput("userBoxplot"))),
tabPanel("Tabelle", fluidPage(tableOutput("userTabelle"))))
))
)
server <- function(input, output) {
userDaten <- reactive({
validate(need(input$userDatei, "Es ist keine Datei ausgewählt."))
req(input$userDatei)
infile <- input$userDaten
if (see_if(has_extension(infile$datapath, 'csv')) == TRUE
| see_if(has_extension(infile$datapath, 'txt')) == TRUE
| see_if(has_extension(infile$datapath, 'TXT')) == TRUE
| see_if(has_extension(infile$datapath, 'CSV')) == TRUE) {
output$dateiformat <- renderText('csvtxt')
outputOptions(output, "dateiformat", suspendWhenHidden = FALSE)
daten <- read.csv(infile$datapath,
header = input$header,
dec = input$dec,
sep = input$sep,
quote = input$quote)}
else {
output$dateiformat <- renderText('xlsx')
daten <- read.xlsx(infile$datapath,
header = input$header,
sheetIndex = 1)}
})
output$userBoxplot <- renderPlot({
validate(
need(input$userDatei, "Es ist keine Datei ausgewählt.") %then%
need(try(
boxplot(x = userDaten()),
TRUE), "Dezimalzeichen und Seperator müssen angepasst werden."))
})
output$userTabelle <- renderTable({
return(userDaten())})
}
shinyApp(ui = ui, server = server)
And this is the content of the .txt file I use to test the app:
A B C
0.509 0.170 0.042
0.071 0.540 0.093
0.623 0.443 0.277
0.290 0.313 0.436
0.925 0.096 0.716
0.358 0.792 0.373
0.269 0.621 0.445
0.205 0.733 0.787
0.953 0.905 0.534
0.881 0.162 0.918
0.332 0.905 0.901