我知道该sink()函数可用于将R输出转移到文件中,例如
sink('sink-closing.txt')
cat('Hello world!')
sink()
Run Code Online (Sandbox Code Playgroud)
是否有一个简单的命令来关闭所有未完成的接收器?
下面,我详细说明我的问题.
假设我的R脚本sink()在R脚本中打开一个,但是在脚本关闭之前R脚本中出现错误sink().我可能多次运行R脚本,试图修复错误.最后,我想关闭所有接收器并打印到控制台.我该怎么办?
最后,为了具体,我提供了一个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()
Run Code Online (Sandbox Code Playgroud)
接下来,我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
Run Code Online (Sandbox Code Playgroud)
现在,假设我正在调试R脚本并想要打印到控制台.我可以sink()多次打电话来关闭早期的接收器.如果我调用它3次,那么我最终可以像以前一样打印到控制台.但我如何知道需要关闭多少水槽?
Das*_*son 35
你可以sink.number()用来告诉你已经设置sink了多少次转移,然后多次调用.把它放到一个函数中就可以了
sink.reset <- function(){
for(i in seq_len(sink.number())){
sink(NULL)
}
}
Run Code Online (Sandbox Code Playgroud)
42-*_*42- 34
closeAllConnections() # .........................
Run Code Online (Sandbox Code Playgroud)
根据@ mnel的评论:
sinkall <- function() {
i <- sink.number()
while (i > 0) {
sink()
i <- i - 1
}
}
Run Code Online (Sandbox Code Playgroud)
应该关闭所有打开的水槽.
在处理设备和绘图时,您可能还会遇到此问题,其中未在任何地方报告打开设备的数量.对于更一般的情况,您可以使用此:
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.
Run Code Online (Sandbox Code Playgroud)
编辑:
sink抛出警告而不是错误所以我修改了代码,以便它不会永远运行,哎呀!
这个问题可以通过使用“on.exit”函数来避免:
sink("output.txt")
on.exit(sink())
my_function_that_might_error()
Run Code Online (Sandbox Code Playgroud)
我遇到这种情况最常见的情况是发生错误导致水槽无法关闭。例如,以下命令在执行后将留下一个打开的接收器。
sink("output.txt")
my_function_that_will_error()
sink()
Run Code Online (Sandbox Code Playgroud)
使用 可以避免这种情况on.exit(sink())。这将“当当前函数退出时(自然退出或由于错误而退出)”(此处的文档)关闭接收器。
但你必须改变顺序:
sink("output.txt")
on.exit(sink())
my_function_that_might_error()
Run Code Online (Sandbox Code Playgroud)
因此,我们创建接收器,告诉 R 在退出时将其关闭,然后执行可能出错的代码。无论代码是否错误,这都会关闭接收器。
请注意,交互运行时, 的行为on.exit可能无法按预期工作。如果该行在on.exit(sink())控制台上运行,则会在所有当前命令结束时立即触发。
因此,这种方法需要获取脚本或在某些 R 函数/进程中创建和关闭接收器。
请参阅文档以on.exit获取更多信息。