如何通过 Shiny App 中的 fileInput 函数验证要上传的 csv 文件?
How to validate csv file for upload via fileInput function in shiny App?
在 运行 下面的“缩写代码”中,我试图创建一个文件上传验证,即要上传的 csv 必须在单元格 A1 和csv 的 B1。否则文件不会被上传并且被标记为“无效”。关于如何执行此操作的任何想法?
如果您 运行 下面,单击单一操作按钮并通过单击模式对话框底部的按钮保存矩阵输入,查看下载的 csv,看看单元格 A1 和 B1从下载的矩阵中显示“场景 1”和“场景 1”。这很好。如果您删除这些并保存 csv,您会看到在 运行 应用程序时仍然可以上传此修改后的 csv。我希望将这 2 个 csv 字段用作验证标志。
我非常喜欢这个应用程序中的 try()
功能作为一个包罗万象的测试。
缩写代码:
library(dplyr)
library(shiny)
library(shinyFeedback)
library(shinyMatrix)
sumMat <- function(x){return(rep(sum(x,na.rm = TRUE), 10))}
ui <- fluidPage(
useShinyFeedback(),
sidebarLayout(
sidebarPanel(
actionButton("matrix3show","Click for matrix input"),
),
mainPanel(plotOutput("plot"))
)
)
server <- function(input, output, session) {
uploadMat3Data <- 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 <- renderPrint(class(uploadMat3Data())),
footer =
tagList(
downloadButton("saveMat3","Save",style = "width:80px;"),
modalButton("Exit box")
) # close tag list
))
})
observeEvent(input$matrix3, {
tmpMat3 <- input$matrix3
colnames(tmpMat3) <- paste("Scenario",rep(1:ncol(tmpMat3),each=2,length.out=ncol(tmpMat3)))
rownames(tmpMat3) <- paste("Row", seq_len(nrow(input$matrix3)))
updateMatrixInput(session,inputId="matrix3",value=tmpMat3)
})
data <- function(){tibble(X = seq_len(10),Y = sumMat(input$matrix3))}
output$plot<-renderPlot({plot(data(),type="l")})
output$saveMat3 <- downloadHandler(
filename = function(){paste("Inputs","csv",sep=".")},
content = function(file){write.csv(input$matrix3, file,row.names=FALSE)}
)
}
shinyApp(ui, server)
为了解决问题,我将 uploadMat3Data()
的 observeEvent
更改为以下内容:
observeEvent(uploadMat3Data(), {
if(is.data.frame(uploadMat3Data())
&& colnames(uploadMat3Data()[1]) == "Scenario.1"
&& colnames(uploadMat3Data()[2]) == "Scenario.1.1"
){
updateMatrixInput(session,"matrix3",as.matrix(uploadMat3Data()))
hideFeedback("uploadMat3")
}
else {showFeedbackWarning("uploadMat3", "Invalid")}
})
请注意添加的 && colnames(...
,其中代码查看上传数据帧的 headers 并检查所需的 headers。另请注意,在原始代码中,hideFeedback()
和 showFeedbackWarning()
中的 id 引用不正确;它们现在更正为“uploadMat3”
在 运行 下面的“缩写代码”中,我试图创建一个文件上传验证,即要上传的 csv 必须在单元格 A1 和csv 的 B1。否则文件不会被上传并且被标记为“无效”。关于如何执行此操作的任何想法?
如果您 运行 下面,单击单一操作按钮并通过单击模式对话框底部的按钮保存矩阵输入,查看下载的 csv,看看单元格 A1 和 B1从下载的矩阵中显示“场景 1”和“场景 1”。这很好。如果您删除这些并保存 csv,您会看到在 运行 应用程序时仍然可以上传此修改后的 csv。我希望将这 2 个 csv 字段用作验证标志。
我非常喜欢这个应用程序中的 try()
功能作为一个包罗万象的测试。
缩写代码:
library(dplyr)
library(shiny)
library(shinyFeedback)
library(shinyMatrix)
sumMat <- function(x){return(rep(sum(x,na.rm = TRUE), 10))}
ui <- fluidPage(
useShinyFeedback(),
sidebarLayout(
sidebarPanel(
actionButton("matrix3show","Click for matrix input"),
),
mainPanel(plotOutput("plot"))
)
)
server <- function(input, output, session) {
uploadMat3Data <- 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 <- renderPrint(class(uploadMat3Data())),
footer =
tagList(
downloadButton("saveMat3","Save",style = "width:80px;"),
modalButton("Exit box")
) # close tag list
))
})
observeEvent(input$matrix3, {
tmpMat3 <- input$matrix3
colnames(tmpMat3) <- paste("Scenario",rep(1:ncol(tmpMat3),each=2,length.out=ncol(tmpMat3)))
rownames(tmpMat3) <- paste("Row", seq_len(nrow(input$matrix3)))
updateMatrixInput(session,inputId="matrix3",value=tmpMat3)
})
data <- function(){tibble(X = seq_len(10),Y = sumMat(input$matrix3))}
output$plot<-renderPlot({plot(data(),type="l")})
output$saveMat3 <- downloadHandler(
filename = function(){paste("Inputs","csv",sep=".")},
content = function(file){write.csv(input$matrix3, file,row.names=FALSE)}
)
}
shinyApp(ui, server)
为了解决问题,我将 uploadMat3Data()
的 observeEvent
更改为以下内容:
observeEvent(uploadMat3Data(), {
if(is.data.frame(uploadMat3Data())
&& colnames(uploadMat3Data()[1]) == "Scenario.1"
&& colnames(uploadMat3Data()[2]) == "Scenario.1.1"
){
updateMatrixInput(session,"matrix3",as.matrix(uploadMat3Data()))
hideFeedback("uploadMat3")
}
else {showFeedbackWarning("uploadMat3", "Invalid")}
})
请注意添加的 && colnames(...
,其中代码查看上传数据帧的 headers 并检查所需的 headers。另请注意,在原始代码中,hideFeedback()
和 showFeedbackWarning()
中的 id 引用不正确;它们现在更正为“uploadMat3”