#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».