如何避免“下沉堆栈已满”#39;当sink()用于捕获foreach循环中的消息时出错

时间:2014-10-10 09:35:37

标签: r foreach cat sink

为了查看在foreach()循环中运行的函数输出的控制台消息,我按照this guy的建议添加了sink()调用,如下所示:

   library(foreach)    
   library(doMC)
   cores <- detectCores()
   registerDoMC(cores)

   X <- foreach(i=1:100) %dopar%{
   sink("./out/log.branchpies.txt", append=TRUE)
   cat(paste("\n","Starting iteration",i,"\n"), append=TRUE)
   myFunction(data, argument1="foo", argument2="bar")
   }

然而,在迭代77我得到了错误&#39; sink stack is full&#39;。有well-answered questions关于在使用for循环时避免此错误,但不是foreach。将其他隐藏的foreach输出写入文件的最佳方法是什么?

3 个答案:

答案 0 :(得分:6)

这在我的Mac上运行没有错误:

library(foreach)    
library(doMC)
cores <- detectCores()
registerDoMC(cores)

X <- foreach(i=1:100) %dopar%{
  sink("log.branchpies.txt", append=TRUE)
  cat(paste("\n","Starting iteration",i,"\n"))
  sink() #end diversion of output
  rnorm(i*1e4)
}

这样更好:

library(foreach)    
library(doMC)
cores <- detectCores()
registerDoMC(cores)
sink("log.branchpies.txt", append=TRUE)
X <- foreach(i=1:100) %dopar%{
  cat(paste("\n","Starting iteration",i,"\n"))
    rnorm(i*1e4)
}
sink() #end diversion of output

这也有效:

library(foreach)    
library(doMC)
cores <- detectCores()
registerDoMC(cores)

X <- foreach(i=1:100) %dopar%{
  cat(paste("\n","Starting iteration",i,"\n"), 
       file="log.branchpies.txt", append=TRUE)
  rnorm(i*1e4)
}

答案 1 :(得分:3)

正如this guy所建议的那样,跟踪接收器堆栈是非常棘手的。因此,建议使用cat的能力写入文件,如上面的答案所示:

cat(..., file="log.txt", append=TRUE)

要保存一些输入,您可以创建一个包装函数,每次调用cat时都会将输出转移到文件:

catf <- function(..., file="log.txt", append=TRUE){
  cat(..., file=file, append=append)
}

最后,当你致电foreach时,你会使用这样的东西:

library(foreach)    
library(doMC)
cores <- detectCores()
registerDoMC(cores)

X <- foreach(i=1:100) %dopar%{
  catf(paste("\n","Starting iteration",i,"\n"))
  rnorm(i*1e4)
}

希望它有所帮助!

答案 2 :(得分:0)

在for循环中调用没有参数的sink()来重置它以在每次迭代结束时结束文件写入,并且不会再次出现此错误。