如何在闪亮的应用程序中显示控制台进度条输出?

问题描述 投票:0回答:1

我目前正在制作一个 Shiny 应用程序,它通过下面示例中的

f()
表示的函数从输入数据集计算相关矩阵。因为需要相当长的时间,所以我想显示一个进度条。在 Rstudio 中,函数
f()
foreach
循环并行运行,并使用
txtProgressbar()
以及
doSNOW
包在控制台中显示进度条。

但是,它实际上是我开发的包的一部分,因此循环没有明确出现在我闪亮的应用程序的

server.R
部分中,我无法应用我在网上找到的任何方法来显示该栏(也不确定如何他们可以处理并行化)。当我运行该应用程序时,该栏出现在 Rstudio 控制台中,但没有显示在闪亮的界面上。

我想在计算矩阵时在我的闪亮应用程序中显示进度条。以下是理解问题所需的代码部分:

  #importing all needed packages

    ui <- fluidPage(
    fileInput("data", "Your data here", accept=".csv"),
    #some other inputs and outputs that work well
    tableOutput("matrix")
    )

    server <- function(input,output){

        # This is my data importation in a reactive object
            dataframe <- reactive({
                file <- input$data
                ext <- tools::file_ext(file$datapath)
                req(file)
                validate(need(ext == "csv", "Please upload a csv file"))
                read.csv2(file$datapath, header = TRUE,sep=";")
                })
        # This is my matrix estimation via my function f()
            mtrx <- reactive({
                f(dataframe())
                })
        # This is the display
           output$matrix <- renderTable({
                mtrx()
                })
        #some other inputs and outputs that work well
    }

我想我应该有一些

renderText
用于
f()
显示的进度条,并在 UI 中的
textOutput
上方显示一个
tableOutput("matrix")
,但我不知道运行时如何访问此对象
f()
仅返回矩阵。

提前感谢您,请随时要求澄清!

r shiny rparallel
1个回答
1
投票

f()
包裹在
ExtendedTask
中,以便能够在运行时更新 UI。 然后将进度条输出重定向到文件中。最后定期阅读 文件内容带有
reactiveFileReader()
显示:

library(shiny)
library(mirai)

f <- function(n) {
  pb <- txtProgressBar(0, n)
  for (i in seq_len(n)) {
    Sys.sleep(0.01)
    setTxtProgressBar(pb, i)
  }
  42
}

ui <- fluidPage(
  actionButton("go", "Go"),
  verbatimTextOutput("progress"),
  verbatimTextOutput("result"),
)

PROGRESS_FILE <- "progress.txt"

server <- function(input, output, session) {
  task <- ExtendedTask$new(function() {
    mirai({
      sink(PROGRESS_FILE)
      on.exit(sink())
      f(100)
    }, f = f, PROGRESS_FILE = PROGRESS_FILE)
  })
  observeEvent(input$go, task$invoke())
  
  progress <- reactiveFileReader(100, session, PROGRESS_FILE, function(path) {
    if (file.exists(path)) readLines(path, 1, warn = FALSE)
  })
  output$progress <- renderText({ progress() })
  observeEvent(task$result(), unlink(PROGRESS_FILE))
  
  output$result <- renderText({ task$result() })
}

shinyApp(ui, server)
© www.soinside.com 2019 - 2024. All rights reserved.