在最底部現在發布了完整的決議代碼,反映了 M. Jagan 提供的解決方案。此代碼提供資料上傳(具有強大的資料驗證)和用戶輸入下載的完整周期。您可以看到該try()函式如何“測驗”上傳以避免不必要的應用程式崩潰。
運行以下代碼時,用戶可以上傳和下載輸入資料。用戶可以下載和保存輸入,然后通過上傳檢索這些輸入。我正在嘗試改進上傳驗證,因為實際上用戶很容易選擇不正確的檔案,我寧愿用警告標記而不是像現在這樣讓應用程式崩潰。
所有下載都保存為帶有 X 和 Y 標題的 2 列矩陣。這(以及它是 CSV 的事實)是我根據以下代碼進行的關鍵上傳驗證。該應用程式正確下載和上傳 CSV 資料,如下面的圖片 1(下載)和圖片 2(上傳)所示,但在嘗試上傳每個圖片 3 格式不正確的 CSV 資料時崩潰。
所以我的問題是:
- 如何指定 csv 檔案中的哪些列來查找“X”和“Y”標題?目前,它到處讀取 X 和 Y 標頭。我嘗試
read.csv(...colClasses=c(NA, NA)))如下所示,我也嘗試過read.csv(...)[ , 1:2],但都不起作用。 - 更一般地說,如果上傳會導致錯誤或崩潰,有沒有辦法中止上傳?有點像
if(iserror(...))Excel - 好的,現在我正在推動它,如果這太多,請隨時忽略它。有什么辦法可以將上傳警告移入
modalDialog?在解決上述問題后,如果我無法弄清楚,我可以隨時將其移至另一個帖子。
MWE代碼:
library(dplyr)
library(shiny)
library(shinyMatrix)
interpol <- function(a, b) { # a = periods, b = matrix inputs
c <- rep(NA, a)
c[1] <- b[1]
c[a] <- b[2]
c <- approx(seq_along(c)[!is.na(c)], c[!is.na(c)], seq_along(c))$y
return(c)
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file1", "Optionally choose input file (csv)", accept = ".csv"),
sliderInput('periods', 'Periods to interpolate over:', min=1, max=10, value=10),
matrixInput("matrix1",
value = matrix(c(1,5),
ncol = 2,
dimnames = list("Interpolate",c("X","Y"))
),
cols = list(names = TRUE),
class = "numeric"
),
downloadButton("download")
),
mainPanel(
tableOutput("contents"),
plotOutput("plot")
)
)
)
server <- function(input, output, session) {
input_file <- reactive({
file <- input$file1
ext <- tools::file_ext(file$datapath)
req(file)
if(is.null(file))
return(NULL)
file_contents <- read.csv(file$datapath,header=TRUE,colClasses=c(NA, NA))
required_columns <- c('X','Y')
column_names <- colnames(file_contents)
shiny::validate(
need(ext == "csv", "Incorrect file type"),
need(required_columns %in% column_names, "Incorrect file type")
)
file_contents
})
output$contents <- renderTable({
input_file()
})
data <- function(){
tibble(
X = seq_len(input$periods),
Y = interpol(input$periods,matrix(c(input$matrix1[1,1],input$matrix1[1,2])))
)
}
output$plot<-renderPlot({plot(data(),type="l",xlab="Periods (X)", ylab="Interpolated Y values")})
observeEvent(input$file1,{
updateMatrixInput(session,
inputId = "matrix1",
value = matrix(as.matrix(input_file()),
ncol=2,
dimnames = list("Interpolate",c("X","Y"))
)
)
})
output$download <- downloadHandler(
filename = function() {
paste("Inputs","csv",sep=".")
},
content = function(file) {
write.csv(input$matrix1, file,row.names=FALSE)
}
)
}
shinyApp(ui, server)




現在解決的代碼:
library(dplyr)
library(shiny)
library(shinyFeedback)
library(shinyMatrix)
nms <- c("X", "Y") # < Matrix variable names (headers)
interpol <- function(a, b) { # < a = periods, b = matrix inputs
c <- rep(NA, a)
c[1] <- b[1]
c[a] <- b[2]
c <- approx(seq_along(c)[!is.na(c)], c[!is.na(c)], seq_along(c))$y
return(c)
}
ui <- fluidPage(
useShinyFeedback(),
sidebarLayout(
sidebarPanel(
fileInput("file", "Optionally choose input file (csv)", accept = ".csv"),
sliderInput('periods', 'Periods to interpolate over:', min=1, max=10, value=10),
matrixInput("matrix1",
"Values to interpolate:",
value = matrix(c(1,5),ncol = 2,dimnames = list(NULL,nms)),
cols = list(names = TRUE),
rows = list(names = FALSE),
class = "numeric"
),
downloadButton("download")
),
mainPanel(
tableOutput("contents"),
plotOutput("plot"),
verbatimTextOutput("verb")
)
)
)
server <- function(input, output, session) {
uploadData <- reactive({
req(input$file)
validate(need(identical(tools::file_ext(input$file$datapath),"csv"),"Invalid extension"))
try(read.csv(input$file$datapath, header = TRUE))
})
observeEvent(uploadData(), {
if(is.data.frame(uploadData()) &&
all(nms %in% names(uploadData())) &&
all(vapply(uploadData()[nms],is.numeric,NA))){
updateMatrixInput(session,"matrix1",as.matrix(uploadData()[nms]))
hideFeedback("file")
}
else {
showFeedbackWarning("file", "Invalid upload.")
}
})
data <- function(){
tibble(
X = seq_len(input$periods),
Y = interpol(input$periods,matrix(c(input$matrix1[1,1],input$matrix1[1,2])))
)
}
output$plot<-renderPlot({plot(data(),type="l",xlab="Periods (X)", ylab="Interpolated Y values")})
output$verb <- renderPrint(class(uploadData()))
output$download <- downloadHandler(
filename = function() {
paste("Inputs","csv",sep=".")
},
content = function(file) {
write.csv(input$matrix1, file,row.names=FALSE)
}
)
}
shinyApp(ui, server)
uj5u.com熱心網友回復:
以下應滿足您的需求
shiny::validate(
need(ext == "csv", "Incorrect file type"),
need(required_columns %in% column_names, "Incorrect file type"),
need(sum(!column_names %in% required_columns)==0, "Incorrect columns in file")
)
更新:如果您可以修改支票,您可以執行以下操作。
shiny::validate(
need(ext == "csv", "Incorrect file type"),
need(sum(required_columns %in% column_names)==2 & sum(!column_names %in% required_columns)==0, "Incorrect file type")
)
uj5u.com熱心網友回復:
我已經創建了您的應用程式的最小版本(沒有插值或下載),我認為它解決了 (1) 和 (2) 以及您希望在發生無效上傳的情況下保留現有矩陣和繪圖的愿望。您應該能夠通過修改此框架來重建您的應用程式,但是在此之前,您應該嘗試了解此應用程式的作業原理。
請注意,我添加了對 package 的依賴shinyFeedback,它將警告訊息放置在適當的輸入面板附近。讓我知道這是否有問題...
library("shiny")
library("shinyFeedback")
library("shinyMatrix")
## Your variable names
nms <- c("X", "Y")
ui <- fluidPage(
useShinyFeedback(),
sidebarLayout(
sidebarPanel(
fileInput("file", label = "CSV file", accept = ".csv"),
matrixInput("mat", label = "Matrix", value = matrix(rnorm(12L), 6L, 2L, dimnames = list(NULL, nms)), class = "numeric", rows = list(names = FALSE))
),
mainPanel(
plotOutput("plot"),
verbatimTextOutput("verb")
)
)
)
server <- function(input, output, session) {
rawdata <- reactive({
req(input$file)
try(read.csv(input$file$datapath, header = TRUE))
})
observeEvent(rawdata(), {
## If 'rawdata()' is a data frame with numeric variables named 'nms'
if (is.data.frame(rawdata()) && all(nms %in% names(rawdata())) && all(vapply(rawdata()[nms], is.numeric, NA))) {
## Then update matrix by extracting those variables, ignoring the rest (if any)
updateMatrixInput(session, "mat", as.matrix(rawdata()[nms]))
## And suppress warning if visible
hideFeedback("file")
} else {
## Otherwise show warning
showFeedbackWarning("file", "Invalid upload.")
}
})
## Plots matrix rows as points
output$plot <- renderPlot(plot(input$mat))
## Prints "try-error" if 'read.csv' threw error, "data.frame" otherwise
output$verb <- renderPrint(class(rawdata()))
}
shinyApp(ui, server)
以下是可用于創建測驗檔案的代碼。每個測驗應用程式的不同行為。
## OK
cat("X,Y,Z\na,1,3,5\nb,2,4,6\n", file = "test1.csv")
## OK: file contents matter, not file extension
cat("X,Y,Z\na,1,3,5\nb,2,4,6\n", file = "test2.txt")
## Missing 'X'
cat("W,Y,Z\na,1,3,5\nb,2,4,6\n", file = "test3.csv")
## 'X' is not numeric
cat("X,Y,Z\na,hello,3,5\nb,world,4,6\n", file = "test4.csv")
## Not a valid CSV file
cat("read.csv\nwill,not,like,this,file\n", file = "test5.csv")
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/362328.html
