我有以下代码可以这样工作:用户上传文件,按下提交,运行外部程序,在输出目录中创建文件,在绘图选项卡和表格选项卡中读取和呈现文件。如果用户在绘图选项卡上按下提交,它可以正常工作;但是如果在表格选项卡处于活动状态时按下该按钮,则它不会更新以使用新创建的表格输出目录。我在下面添加了一些通用代码,由于工作的性质,无法提供具体示例。
我已尝试通过添加observeEvent
来解决此问题,以便在按下按钮时切换到绘图标签,但它不起作用。我猜测它与按下按钮时激活的标签有关,所以它首先执行output$table1 <- DT::renderDataTable({ ... })
中的代码仍然引用output.dir
的旧内容。当此选项卡处于活动状态时,按下按钮时有没有办法停止它?或者我应该以不同的方式格式化代码流?仍在努力想出闪亮的感觉。
按下按钮时,无论哪个标签处于活动状态,我都需要按照上面指定的顺序进行操作。新目录,运行命令并输出到目录,然后在每个选项卡中从中读取文件。我让它切换到图表,因为你首先查看交互表。每次按提交时,都应呈现新的更新图表和表格。
ui.R
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file1", "Upload a file"),
actionButton("submitButton", "Submit")
),
mainPanel(
tabsetPanel(id = "output",
tabPanel("Graph",plotOutput("plot1")),
tabPanel("Interactions", DT::dataTableOutput("table1"))
)
)
)
))
server.R
shinyServer(function(input, output, session) {
# When button pressed, create output directory and switch to plot tab
observeEvent(input$submitButton, {
updateTabsetPanel(session, "output", "Graph")
dateTime <- as.numeric(as.POSIXct(Sys.time()))
output.dir <<- paste0("~/Sites/Shiny/",dateTime,"/")
dir.create(output.dir)
})
output$plot1 <- renderPlot({
# Check if button pressed and only run if pressed
input$submitButton
isolate({
validate(
need(input$file1, 'Provide a file')
)
})
# External system commands which creates output files in output.dir
# Concatenate some strings for arguments, then run system(...)
# Capture output, check for error string and validate
validate(
need(!(gdata::startsWith(output, "Error:")), 'Error: ...')
)
plot(readLines(paste0(output.dir,"plot.file")))
})
output$table1 <- DT::renderDataTable({
# Check if button pressed and only run if pressed
input$submitButton
isolate({
validate(
# Make sure files exist in the directory
need(length(list.files(output.dir,pattern="^StartsWithA|^StartsWithB")) > 0,
'Run model first to receive interactions')
)
DT::datatable(read.table(
paste0(output.dir,list.files(output.dir,pattern="^StartsWithA|^StartsWithB")),
col.names = c("ColA","ColB","ColC","ColD"), sep="\t"),
options = list(pageLength = 10))
})
})
})
答案 0 :(得分:4)
我重写了函数的顺序,并将所有内容包装在observeEvent
中,并将系统调用移到输出之外,现在看来它可以正常工作。
shinyServer(function(input, output, session) {
output$plot1 <- renderPlot({
validate(
need(input$file1, 'Provide a file')
)
})
output$table1 <- DT::renderDataTable({
validate(
need(input$file1, 'Provide a file')
)
})
# When button pressed, create output directory, switch to plot tab, run program
observeEvent(input$submitButton, {
input$submitButton
isolate({
validate(
need(input$file1, 'Provide a file')
)
})
updateTabsetPanel(session, "output", "Graph")
dateTime <- as.numeric(as.POSIXct(Sys.time()))
output.dir <<- paste0("~/Sites/Shiny/",dateTime,"/")
dir.create(output.dir)
# External system commands which creates output files in output.dir
# Concatenate some strings for arguments, then run system(...)
# Capture output, check for error string and validate
command.output <- system(..., intern=T)[1]
output$plot1 <- renderPlot({
validate(
need(!(gdata::startsWith(command.output, "Error:")), 'Error: ...')
)
plot(readLines(paste0(output.dir,"plot.file")))
})
output$table1 <- DT::renderDataTable({
validate(
need(!(gdata::startsWith(command.output, "Error:")), 'Error: ...')
)
DT::datatable(read.table(
paste0(output.dir,list.files(output.dir,pattern="^StartsWithA|^StartsWithB")),
col.names = c("ColA","ColB","ColC","ColD"), sep="\t"),
options = list(pageLength = 10))
})
})
})