抑制R中安装输出信息

13

这真的开始困扰我了... 我尝试了几种方法,但似乎都不起作用。

我正在运行一个函数安装程序,它会生成许多不必要的消息,我想要抑制它们,但我尝试过的所有方法都没有成功。

我要抑制的代码部分是:install_github('ROAUth', 'duncantl'),它需要先加载devtools包。

无论如何,我尝试了invisiblecapture.outputsink,但都不起作用...或者我可能没有正确使用它们...无论哪种情况...有什么建议吗?


3
也许 suppressMessages()suppressPackageStartupMessages() 是你想要的? - Chase
1
@Chase是正确的。你在另一个问题中的函数有些复杂,不应该每次调用install_github()。请参见我在那里的答案。 - Maiasaura
4个回答

10

suppressMessages函数可以关闭一些通过message函数打印出来的信息,但不是所有的信息都可以被关闭。

其余的信息是由于通过system2函数调用R CMD INSTALL而产生的。我认为这是因为这是一个外部命令,所以你尝试的所有常规方法(如sinkcapture.output等)都无法工作。请注意,system2函数带有stderrstdout参数,如果将它们设置为FALSE,则会关闭所有这些消息。不幸的是,system2默认使用stdout = ""stderr = "",似乎没有办法通过devtools包访问这些参数。

因此,我找到的一种在没有任何消息的情况下运行的方法是暂时覆盖基础环境中的system2函数。虽然这不是特别优雅,但它可以运行:

# store a copy of system2
assign("system2.default", base::system2, baseenv())

# create a quiet version of system2
assign("system2.quiet", function(...)system2.default(..., stdout = FALSE,
                                                     stderr = FALSE), baseenv())

# overwrite system2 with the quiet version
assignInNamespace("system2", system2.quiet, "base")

# this is now message-free:
res <- eval(suppressMessages(install_github('ROAUth', 'duncantl'))) 

# reset system2 to its original version
assignInNamespace("system2", system2.default, "base")

在尝试了其他所有方法之后,我将相同的想法应用于systeminstall.packages。太棒了。 - piccolbo

3
另一种技术是修补devtools函数,使其允许您将stdout参数传递给system2。这也不是很好的解决方案,但也许您可以说服软件包作者以此修改devtools。以下是我修改过的build和install函数:
library(devtools)

# New functions.
my.install<-function (pkg = ".", reload = TRUE, quick = FALSE, args = NULL, ...) 
{
    pkg <- as.package(pkg)
    message("Installing ", pkg$package)
    devtools:::install_deps(pkg)
    built_path <- devtools:::build(pkg, tempdir(),...) # pass along the stdout arg
    on.exit(unlink(built_path))
    opts <- c(paste("--library=", shQuote(.libPaths()[1]), sep = ""), 
        "--with-keep.source")
    if (quick) {
        opts <- c(opts, "--no-docs", "--no-multiarch", "--no-demo")
    }
    opts <- paste(paste(opts, collapse = " "), paste(args, collapse = " "))
    devtools:::R(paste("CMD INSTALL ", shQuote(built_path), " ", opts, sep = ""),...) # pass along the stdout arg
    if (reload) 
        devtools:::reload(pkg)
    invisible(TRUE)
}

my.build<-function (pkg = ".", path = NULL, binary = FALSE, ...) 
{
    pkg <- as.package(pkg)
    if (is.null(path)) {
        path <- dirname(pkg$path)
    }
    if (binary) {
        cmd <- paste("CMD INSTALL ", shQuote(pkg$path), " --build", 
            sep = "")
        ext <- if (.Platform$OS.type == "windows") 
            "zip"
        else "tgz"
    }
    else {
        cmd <- paste("CMD build ", shQuote(pkg$path), " --no-manual --no-resave-data", 
            sep = "")
        ext <- "tar.gz"
    }
    devtools:::R(cmd, path, ...) # pass along the stdout arg
    targz <- paste(pkg$package, "_", pkg$version, ".", ext, sep = "")
    file.path(path, targz)
}

# Patch package.
unlockBinding("install", as.environment("package:devtools"))
unlockBinding("build", as.environment("package:devtools"))
assignInNamespace('install', my.install, ns='devtools', envir=as.environment("package:devtools"));
assignInNamespace('build', my.build, ns='devtools', envir=as.environment("package:devtools"));
lockBinding("install", as.environment("package:devtools"))
lockBinding("build", as.environment("package:devtools"))

# Run with no messages.
suppressMessages(install_github('ROAUth','duncantl',stdout=NULL))

基本上,在install函数中,你需要在三个地方传递...,两次在install函数中,一次在build函数中。


3

这里还有另一种可能性。优点在于您不需要在调用install_github后重置system2:对于所有调用,system2将继续展示其默认行为,除非是由调用install_github()引起的调用:

# store a copy of system2
assign("system2.default", base::system2, baseenv())

# create a quiet version of system2
assign("system2.quiet", function(...)system2.default(..., stdout = FALSE,
                                                     stderr = FALSE), baseenv())
# redefine system2 to use system2.quiet if called from "install_github"
assignInNamespace("system2",
    function(...) {
        cls <- sys.calls()
        from_install_github <- 
            any(sapply(cls, "[[", 1) == as.name("install_github"))
        if(from_install_github) {
            system2.quiet(...)
        } else {
            system2.default(...)
        }},
    "base")


## Try it out
library(devtools)
suppressMessages(install_github('ROAUth', 'duncantl'))

1
install.packages的情况下,有一个quiet开关可以启用以抑制输出。
请参阅install.packages文档了解更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接