R语言 接收器不释放文件

uyto3xhc  于 12个月前  发布在  其他
关注(0)|答案(4)|浏览(89)

我知道sink()函数可以用来将R的输出转移到一个文件中,例如。

sink('sink-closing.txt')
cat('Hello world!')
sink()

字符串
是否有一个简单的命令来关闭所有未完成的接收器?
下面,我详细说明我的问题。
假设我的R-script在R-script中打开sink(),但是在脚本关闭sink()之前,R-script中出现了一个错误。我可能会多次运行R-script,试图修复错误。最后,我想关闭所有接收器并打印到控制台。如何操作?
最后,为了具体起见,我提供了一个MWE来说明我所面临的问题。
首先,我写了一个R脚本sink-closing.R,其中有一个错误。

sink('sink-closing.txt')

foo <- function() {
  cat(sprintf('Hello world! My name is %s\n', 
              a.variable.that.does.not.exist))
}

foo()

sink()


接下来,我source R脚本多次,说3次错误,因为我试图找到并修复错误。

> source('~/Dropbox/cookbook/r-cookbook/sink-closing.R')
Error in sprintf("Hello world! My name is %s\n", a.variable.that.does.not.exist) : 
  object 'a.variable.that.does.not.exist' not found


现在,假设我正在调试R脚本,并希望打印到控制台。我可以多次调用sink()来关闭之前的接收器。如果我调用它3次,那么我最终可以像以前一样打印到控制台。但是我如何知道我需要关闭多少个接收器?

wbgh16ku

wbgh16ku1#

closeAllConnections()   # .........................

字符串
随着时间的推移,我得到了更多的支持,沿着,但西蒙·萨和其他人更好。

i7uaboj4

i7uaboj42#

你可以使用sink.number()来告诉你已经设置了多少个分流,然后调用sink很多次。

sink.reset <- function(){
    for(i in seq_len(sink.number())){
        sink(NULL)
    }
}

字符串

um6iljoc

um6iljoc3#

根据@mnel的评论:

sinkall <- function() {
  i <- sink.number()
  while (i > 0) {
    sink()
    i <- i - 1
  }
}

字符串
应关闭所有开放的Flume。
在处理设备和绘图时,您也可能遇到此问题,其中打开的设备的数量不会在任何地方报告。对于更一般的情况,您可以使用以下命令:

stopWhenError <- function(FUN) {
  tryCatch({
    while(TRUE) {
      FUN()
    }
  }, warning = function(w) {
    print("All finished!")
  }, error = function(e) {
    print("All finished!")
  })
}

stopWhenError(sink) # for sink.
stopWhenError(dev.off) # close all open plotting devices.

编辑:sink抛出了一个警告而不是错误,所以我修改了代码,这样它就不会永远运行,哎呀!

kwvwclae

kwvwclae4#

完全避免问题

这个问题可以通过使用'on.exit'函数来避免:

sink("output.txt")
on.exit(sink())
my_function_that_might_error()

字符串

说明

我遇到的最常见的情况是当发生错误时,阻止接收器关闭。例如,下面的代码将在执行后保留一个打开的接收器。

sink("output.txt")
my_function_that_will_error()
sink()


这可以通过使用on.exit(sink())来避免。这将在“当前函数退出时(自然退出或由于错误退出)”关闭接收器(documentation here)。
但你必须改变顺序:

sink("output.txt")
on.exit(sink())
my_function_that_might_error()


因此,我们创建了接收器,告诉R在它退出时关闭它,然后执行可能出错的代码。这将关闭接收器,而不管代码是否出错。

限制

注意,on.exit的行为在交互式运行时可能不会像预期的那样工作。如果on.exit(sink())行在控制台上运行,它会在所有当前命令结束时立即触发。
因此,这种方法需要在某个R函数/进程中创建并关闭脚本或接收器。
有关详细信息,请参阅on.exit的文档。

相关问题