我知道网上已经有一些材料可以回答我的问题,但它们似乎都不适合我。我想那是因为我不太了解Shiny的反应式编程。
因此,我希望创建一个界面,让用户使用fileInput
选择文件,并仅在单击“上传”按钮时上传。我尝试了各种论坛的一些解决方案,但都没有。以下是我最近的尝试:
#ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel(""),
sidebarPanel(
fileInput("in_file", "Input file:",
accept=c("txt/csv", "text/comma-separated-values,text/plain", ".csv")),
checkboxInput(inputId="is_header", label="Does the input file have column names?", value=TRUE),
actionButton("upload_data", "Upload Data"),
),
mainPanel(
tabsetPanel(
tabPanel("Original Data", tableOutput("orig_data"))
)
)
))
#server.R
library(shiny)
shinyServer(function(input, output, session) {
ra_dec_data <- reactive({
if(input$upload_data==0)
return(NULL)
return(isolate({
head(read_data(input$in_file$datapath, input$in_file$is_header), 50)
}))
})
output$orig_data <- renderTable({
ra_dec_data()
})
})
我面临的问题是,文件一经选中就会上传,而“上传”按钮则无响应。
我的猜测是,我所做的事情没有意义,所以请接受我的道歉,因为这样做非常糟糕。任何帮助将非常感激。谢谢!
答案 0 :(得分:6)
fileInput
直接上传文件,因此我建议您创建自己的“fileInput”。
以下是我将如何进行:
Server.R
library(shiny)
shinyServer(function(input, output, session) {
observe({
if (input$browse == 0) return()
updateTextInput(session, "path", value = file.choose())
})
contentInput <- reactive({
if(input$upload == 0) return()
isolate({
writeLines(paste(readLines(input$path), collapse = "\n"))
})
})
output$content <- renderPrint({
contentInput()
})
})
Ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("Example"),
sidebarPanel(
textInput("path", "File:"),
actionButton("browse", "Browse"),
tags$br(),
actionButton("upload", "Upload Data")
),
mainPanel(
verbatimTextOutput('content')
)
))
在“Server.R”中,我们首先在每次点击动作按钮“浏览”时更新文本输入的值。
“contentInput”是一个反应函数,当输入值(包含在函数体中)被更改时,它将被重新执行,“input $ upload”在这里,而不是当“input $ path”因为我们隔离它而改变时。如果我们没有隔离包含“input $ path”的部分,那么每次我们浏览新文件时都会重新执行“contentInput”,然后上传按钮在这里就没用了。
然后我们在“output $ content”中返回“contentInput”的结果。
希望得到这个帮助。
我意识到,如果您取消选择该文件会产生错误并且闪亮的应用程序崩溃,那么您应该使用Henrik Bengtsson(https://stat.ethz.ch/pipermail/r-help/2007-June/133564.html)的此功能:
file.choose2 <- function(...) {
pathname <- NULL;
tryCatch({
pathname <- file.choose();
}, error = function(ex) {
})
pathname;
}