Раковина не выпускает файл
Я знаю что sink()
функция может использоваться для перенаправления вывода R в файл, например
sink('sink-closing.txt')
cat('Hello world!')
sink()
Есть ли простая команда закрыть все выдающиеся раковины?
Ниже я уточняю свой вопрос.
Предположим, что мой 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()
Далее я 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 раза, то смогу наконец распечатать на консоль, как и раньше. Но как мне узнать, сколько раковин мне нужно закрыть?
4 ответа
Ты можешь использовать sink.number()
сказать, сколько диверсий уже установлено, а затем позвонить sink
это много раз. Поместив это в функцию, вы могли бы иметь это
sink.reset <- function(){
for(i in seq_len(sink.number())){
sink(NULL)
}
}
Основано на комментарии @mnel:
sinkall <- function() {
i <- sink.number()
while (i > 0) {
sink()
i <- i - 1
}
}
Следует закрыть все открытые раковины.
Вы также можете столкнуться с этой проблемой при работе с устройствами и графиками, где количество открытых устройств нигде не сообщается. Для более общего случая вы можете использовать это:
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
выдает предупреждение, а не ошибку, поэтому я изменил код, чтобы он не работал вечно, к сожалению!
Чаще всего я сталкиваюсь с этим, когда возникает ошибка, препятствующая закрытию приемника. Например, следующее оставит открытый приемник после выполнения.
sink("output.txt")
my_function_that_will_error()
sink()
Этого можно избежать, используя
on.exit(sink())
. Это закроет приемник «при выходе текущей функции (естественно или в результате ошибки)» (документация здесь ).
Но вы должны изменить порядок:
sink("output.txt")
on.exit(sink())
my_function_that_might_error()
Итак, мы создаем приемник, говорим R закрыть его при выходе, а затем выполняем код, который может привести к ошибке. Это закроет приемник независимо от того, ошибки кода или нет.