2014-06-10 97 views
7

希望有人能幫助我。定期捕捉cat輸出的R閃亮輸出(renderPrint)

比方說,有一個函數「例子」,這是類似於

##function from a package 

example<-function(f){ 
     #does something 
     cat("step 1 done....") 
     # etc etc 
     cat("step 2 done....") 
     return(some_data_frame) 
} 

##server ui code 
example2<-reactive({ 
     if(input$some_action_button==0) 
      return() 
     result<-isolate(example(input$f1)) 
     return(result) 
}) 

output$f2<-renderPrint({ 
     example2() 
}) 

是否有某種方式來捕獲功能的「貓」輸出到renderPrint,定期?假設這是一個很長的函數來處理,並且用戶獲得一些feedbabk會很好。 invalidateLater對於已經在函數中的東西不起作用(至少在我這裏試過時似乎是這樣的)。

此外,作爲次要問題,以上述方式編寫代碼會導致renderPrint同時捕獲「cat」和data.frame,可能是因爲「返回」。

如果有人能指出我正確的方向,這將是最有幫助的!謝謝!

回答

3

首先,我一直在想這個問題。

因爲shiny是單線程的,所以捕捉函數輸出並將其顯示爲我所知道的有點棘手。

解決此問題的方法是使用非阻塞文件連接,並在讀取函數輸出的文件時運行要從後臺捕獲輸出的函數(檢查編輯歷史記錄以瞭解如何執行此操作)。

這樣做,這將是壓倒一切的貓函數寫入到stderr(簡單地切換catmessage)和捕捉功能輸出這樣的另一種方式:

library(shiny) 
library(shinyjs) 

myPeriodicFunction <- function(){ 
    for(i in 1:5){ 
    msg <- paste(sprintf("Step %d done.... \n",i)) 
    cat(msg) 
    Sys.sleep(1) 
    } 
} 

# Override cat function 
cat <- message 

runApp(shinyApp(
    ui = fluidPage(
    shinyjs::useShinyjs(), 
    actionButton("btn","Click me"), 
    textOutput("text") 
), 
    server = function(input,output, session) { 
    observeEvent(input$btn, { 
     withCallingHandlers({ 
     shinyjs::text("text", "") 
     myPeriodicFunction() 
     }, 
     message = function(m) { 
     shinyjs::text(id = "text", text = m$message, add = FALSE) 
     }) 
    }) 
    } 
)) 

這個例子主要是基於this提問。 daattali。

+0

不錯;但用'shinyjs :: html'替換'shinyjs :: text',並用html = m $ message替換text參數 –