R包开发如何抑制从依赖包生成的消息?

R package development how to suppress messages generated from dependency package?

我正在开发一个名为 VSHunter 的 R 包,需要 NMF 包作为依赖项,但是,每次加载 NMF 都会抛出很多消息,我不知道如何抑制它们。

> devtools::load_all(".")
Loading VSHunter
Loading required package: NMF
Loading required package: pkgmaker
Loading required package: registry

Attaching package: ‘pkgmaker’

The following object is masked from ‘package:base’:

    isFALSE

Loading required package: rngtools
Loading required package: cluster
NMF - BioConductor layer [OK] | Shared memory capabilities [NO: 
bigmemory] | Cores 7/8
  To enable shared memory capabilities, try: install.extras('
NMF
')

我不想打扰用户并期待结果

> devtools::load_all(".")
Loading VSHunter

> library(VSHunter)
Loading VSHunter

在使用 devtools::load_all:

加载包时,您可以采取一些措施来减少噪音
  • devtools::load_all(..., quiet = TRUE) 处理 this 单个包的消息,但不一定是依赖包
  • 尝试在 onLoad 函数中显式加载 ./R/zzz.R 中所需的包。例如:

    .onLoad <- function(libname, pkgname) {
      invisible(suppressPackageStartupMessages(
        sapply(c("tibble", "purrr", "dplyr", "tidyr", "ggplot2", "data.table"),
               requireNamespace, quietly = TRUE)
      ))
    }
    

    (顺便说一句:我在这里使用 sapply 是为了懒惰,并不是说它增加了很多东西。它很容易成为一个 for 循环而没有任何后果。)

    有关使用 requireNamespace 代替 library 的讨论,请参阅 "library vs require", and "Writing R Extensions" 中的说明

    R code in the package should call library or require only exceptionally. Such calls are never needed for packages listed in ‘Depends’ as they will already be on the search path. It used to be common practice to use require calls for packages listed in ‘Suggests’ in functions which used their functionality, but nowadays it is better to access such functionality via :: calls.

    我们正在做的事情在技术上不是必需的,但我认为通过强制这样做,它鼓励更安静的操作。 (这骑在

    注意我使用了 suppressPackageStartupMessages。 "Courteous" 包维护者使用 packageStartupMessage 而不是 message 作为他们的加载消息:后者需要更多的工作并且比前者更不歧视,它很容易被抑制而不会产生意想不到的后果。有很多包不这样做,对此我认为提交 PR 来修复是公平的。

    关于 requireNamespace 的另一条评论:这意味着那些包中的函数将不在 R 会话的搜索路径中。如果用户将始终使用某些包(例如 data.tabledplyr),那么您可能希望使用 library 显式加载它们。再次来自 "Writing R Extensions"

    Field ‘Depends’ should nowadays be used rarely, only for packages which are intended to be put on the search path to make their facilities available to the end user (and not to the package itself): for example it makes sense that a user of package latticeExtra would want the functions of package lattice made available.

    但是,如果您对自己的包很好,那么无论如何您都会对所有非基本包使用 :: 表示法。当然,您可以使用 :: 绕过一些方法,但是 (1) CRAN 检查有时会相当激烈,(2) 显式通常是 "A Good Thing (tm)",并且 (3) 它实际上可以使可维护性变得更容易(例如,当依赖包更改了它们的 API/ABI 并且您需要检查对其包的所有调用时,搜索 pkgname:: 比单独搜索它们的每个函数要容易得多)。

  • 一些软件包使用 .onLoad 过于宽松,做一些并非绝对必要的事情 and/or 会产生不必要的副作用。为此,您始终可以编写一个函数,例如 load_deppkgs_silently(updatesearchpath=TRUE) ,可以手动调用或在存在选项的情况下加载。 (我在这里考虑的是您的最终用户,我非常喜欢提供灵活性和按我的方式加载内容的能力。)