Как проверить csv-файл для загрузки с помощью функции fileInput в приложении shiny?

#r #validation #shiny #upload

Вопрос:

При выполнении приведенного ниже «сокращенного кода» я пытаюсь создать проверку загрузки файла, чтобы в загружаемом csv должны быть «Сценарий 1» и «Сценарий 1» в ячейках A1 и B1 csv. В противном случае файл не загружается и помечается как «недопустимый». Есть идеи, как это сделать?

Если вы выполните описанное ниже, нажмите кнопку «Одно действие» и сохраните входные данные матрицы, нажав кнопку в нижней части модального диалогового окна, просмотрите загруженный csv и посмотрите, как в ячейках A1 и B1 отображаются «Сценарий 1» и «Сценарий 1» из загруженной матрицы. Это хорошо. Если вы удалите их и сохраните файл csv, вы увидите, что этот измененный файл csv все еще можно загрузить при запуске приложения. Я бы хотел, чтобы эти 2 поля csv служили флагом проверки.

Мне очень нравится try() функция комплексного тестирования в этом приложении.

Сокращенный код:

 library(dplyr) library(shiny) library(shinyFeedback) library(shinyMatrix)  sumMat lt;- function(x){return(rep(sum(x,na.rm = TRUE), 10))}  ui lt;- fluidPage(  useShinyFeedback(),  sidebarLayout(  sidebarPanel(  actionButton("matrix3show","Click for matrix input"),  ),  mainPanel(plotOutput("plot"))  ) )  server lt;- function(input, output, session) {    uploadMat3Data lt;- reactive({  req(input$uploadMat3)  validate(need(identical(tools::file_ext(input$uploadMat3$datapath),"csv"),"Invalid"))  try(read.csv(input$uploadMat3$datapath, header = TRUE))  })    observeEvent(uploadMat3Data(), {  if(is.data.frame(uploadMat3Data())){  updateMatrixInput(session,"matrix3",as.matrix(uploadMat3Data()))  hideFeedback("file")  }   else {showFeedbackWarning("file", "Invalid")}  })    observeEvent(input$matrix3show,{  showModal(  modalDialog(  fileInput(inputId = "uploadMat3",label = NULL,accept = ".csv"),  matrixInput(  inputId = "matrix3",  value = if(is.null(input$matrix3)){matrix(c(1,5),ncol=2,dimnames=list(NULL,rep("Scenario 1",2)))}  else {input$matrix3},  rows = list(extend = TRUE, delete = TRUE),  cols = list(extend = TRUE, delta = 2, delete = TRUE, multiheader = TRUE),  class = "numeric"),  output$verbMat3 lt;- renderPrint(class(uploadMat3Data())),  footer =   tagList(  downloadButton("saveMat3","Save",style = "width:80px;"),  modalButton("Exit box")  ) # close tag list  ))  })   observeEvent(input$matrix3, {  tmpMat3 lt;- input$matrix3  colnames(tmpMat3) lt;- paste("Scenario",rep(1:ncol(tmpMat3),each=2,length.out=ncol(tmpMat3)))  rownames(tmpMat3) lt;- paste("Row", seq_len(nrow(input$matrix3)))  updateMatrixInput(session,inputId="matrix3",value=tmpMat3)  })    data lt;- function(){tibble(X = seq_len(10),Y = sumMat(input$matrix3))}     output$plotlt;-renderPlot({plot(data(),type="l")})    output$saveMat3 lt;- downloadHandler(  filename = function(){paste("Inputs","csv",sep=".")},  content = function(file){write.csv(input$matrix3, file,row.names=FALSE)}  ) }  shinyApp(ui, server)  

Ответ №1:

Чтобы решить эту проблему, я изменил observeEvent значение » для uploadMat3Data() » на следующее:

 observeEvent(uploadMat3Data(), {  if(is.data.frame(uploadMat3Data())   amp;amp; colnames(uploadMat3Data()[1]) == "Scenario.1"  amp;amp; colnames(uploadMat3Data()[2]) == "Scenario.1.1"  ){  updateMatrixInput(session,"matrix3",as.matrix(uploadMat3Data()))  hideFeedback("uploadMat3")  }   else {showFeedbackWarning("uploadMat3", "Invalid")}  })  

Обратите внимание на дополнения amp;amp; colnames(... , в которых код заглядывает в заголовки загруженного фрейма данных и проверяет наличие необходимых заголовков. Также обратите внимание, что в исходном коде ссылки на идентификатор в hideFeedback() и showFeedbackWarning() были неверными; теперь они исправлены на «uploadMat3».