2014-06-10 184 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参数 –