Отключение команды cat

Предположим, у меня есть следующая функция:

## Just an example
f = function() { 
  for(i in 1:10000)
      cat(i)
  return(1)
}

Когда я вызываю f(), есть ли способ остановить cat печать на экране (ни в коем случае не изменяя функцию)?

Причина этого вопроса

Мои студенты загружают свои файлы R. Затем я запускаю сценарии и проверяю их правильность. Время от времени студент уходит в команду cat. Это особенно раздражает, когда он находится в длинном цикле for


r cat
person csgillespie    schedule 15.03.2011    source источник


Ответы (5)


В Linux вы можете использовать вызов sink() для /dev/null (или для временного файла в другой ОС, см. ?tempfile):

sink(file="/dev/null")
f()
sink()
person juba    schedule 15.03.2011
comment
sink очень полезно. Однако он также поглотит возвращаемое значение функции. - person Sacha Epskamp; 15.03.2011
comment
@Sacha очевидное решение — присвоить результат f() объекту. - person Gavin Simpson; 15.03.2011
comment
Или в одну строку capture.output(x <- f()) - person hadley; 15.03.2011

Это должно работать?

oldcat = cat
cat = function( ..., file="", sep=" ", fill=F, labels=NULL, append=F ) {}
f()
cat = oldcat

Просто замените cat пустым function, а затем установите его обратно по завершении.

person tim_yates    schedule 15.03.2011
comment
cat <- function(...) {} было бы проще - person hadley; 15.03.2011
comment
или даже cat <- list, если cat появляется только в функциях. - person G. Grothendieck; 15.03.2011
comment
cat <- list кажется немного тупым. Я уверен, что мне пришлось бы прочитать это 3 или 4 раза, чтобы вспомнить, что я делал... - person tim_yates; 15.03.2011
comment
rm(cat) также восстановит cat, удалив версию в глобальной среде, чтобы она не маскировала версию в базе. Также мы можем исключить необходимость в oldcat, так как на него всегда можно ссылаться как base::cat. - person G. Grothendieck; 29.12.2015

Вот забавный прием, который закомментирует все cat() в функции. Не уверен, что это дает ошибки или нарушает функцию:

foo <- deparse(f)
f <- eval(parse(text=gsub("cat","#cat",foo)))

f()

[1] 1

Редактировать:

Другой вариант - это, по сути, ответ Джубы, использующий приемник, но вы можете использовать пакет Defaults, чтобы изменить поведение cat по умолчанию. Аргумент file в основном помещает свой вывод в файл. Так :

library("Defaults")
setDefaults(cat,file="sink.txt")

f()

Гарантирует, что только вывод cat, а не print или около того, погружается. Однако это резко сокращает время выполнения, поскольку теперь файл открывается и закрывается каждый раз при запуске cat().

person Sacha Epskamp    schedule 15.03.2011
comment
Ой! Эта первая идея убьет код ваших учеников, если они где-нибудь использовали буквы «кошка»! Например, переменная под названием "каталог"... - person Spacedman; 15.03.2011
comment
Вы должны использовать регулярное выражение для этого: gsub("^cat$", "#cat", foo) - person aL3xa; 15.03.2011
comment
Старый старый ответ. Но обратите внимание, что это также нарушит многострочные вызовы cat. - person Oliver; 11.05.2020

capture.output() с invisible() делает то, что вы хотите:

f <- function() {
    cat("Hello")
    return(TRUE)
}
f1 <- function() {
    invisible(capture.output(f()))
}
x <- f1()

Это также работает:

f2 <- function() {
    tmp <- tempfile()
    sink(tmp)
    on.exit(sink())
    on.exit(file.remove(tmp), add = TRUE)
    invisible(force(f())) 
}
x <- f2()
person Artem Klevtsov    schedule 29.12.2015

Функция quietly() из библиотеки purrr создает тихую версию функции:

library(purrr)
f <- function() {
    cat("Hello")
    return(TRUE)
}
f2 <- quietly(f)
f2()
#> $result
#> [1] TRUE
#> 
#> $output
#> [1] "Hello"
#> 
#> $warnings
#> character(0)
#> 
#> $messages
#> character(0)
person dash2    schedule 11.09.2019