Разработка пакета R, как подавить сообщения, генерируемые из пакета зависимостей? - PullRequest
0 голосов
/ 27 декабря 2018

Я разрабатываю пакет R под названием VSHunter и мне нужен пакет 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

1 Ответ

0 голосов
/ 27 декабря 2018

Вот несколько вещей, которые вы можете сделать, чтобы уменьшить шум при загрузке пакетов с devtools::load_all:

  • devtools::load_all(..., quiet = TRUE) обрабатывает сообщения для этого отдельного пакета, но не обязательнозависимые пакеты
  • попробуйте явно загрузить требуемые пакеты в ./R/zzz.R в функции onLoad.Например:

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

    (Кстати: я использовал здесь sapply для лени, а не для того, чтобы это много добавляло к вещам. Это мог легко быть цикл for без последствий.)

    Для обсуждения использования requireNamespace вместо library см. "библиотека против требует" и "Запись расширений R" где указано

    R код в пакете должен вызывать библиотеку или требовать только в исключительных случаях.Такие вызовы никогда не нужны для пакетов, перечисленных в «Зависит от», поскольку они уже будут в пути поиска.Раньше было обычной практикой использовать требование вызовов для пакетов, перечисленных в разделе «Предложения», в функциях, которые использовали их функциональные возможности, но в настоящее время лучше получить доступ к такой функции через :: вызовы.

    То, что мы делаем, технически не требуется, но я думаю, что, заставляя делать это таким образом, мы поощряем более тихую работу.(Это относится к

    . Обратите внимание, что я использовал suppressPackageStartupMessages. "Вежливые" сопровождающие пакетов используют packageStartupMessage вместо message для своих сообщений о загрузке: последний требует немного больше работы иявляется гораздо менее дискриминирующим, чем первый, который очень легко подавляется без непредвиденных последствий. Есть много пакетов, которые этого не делают, и я думаю, что было бы справедливо представить PR для исправления.

    Еще один комментарий о requireNamespace: это означает, что функции в этих пакетах не будут находиться в пути поиска сеансов R. Если пользователь всегда будет использовать определенные пакеты (например, data.table или dplyr), тогда вы можете явно захотетьзагрузите их library. Из «Запись R-расширений» снова:

    В настоящее время поле «Зависит» следует использовать редко, только для пакетов, которые предназначены для надеванияпуть поиска, чтобы сделать их средства доступными для конечного пользователя (а не для самого пакета): например, имеет смысл, что пользователь пакета latticeExtraхотел бы, чтобы функции решетки пакета были доступны.

    Однако, если вы хорошо относитесь к своему пакету, то вы все равно используете нотацию :: для всех не базовых пакетов.Конечно, есть способы, которыми вы можете обойтись, используя ::, но (1) проверки CRAN иногда бывают довольно интенсивными, (2) явным обычно является «Хорошая вещь (tm)», и (3) это может значительно повысить удобство сопровождения.проще (например, когда зависимый пакет меняет свой API / ABI, и вам необходимо проверить все вызовы их пакета, где поиск pkgname:: намного проще, чем поиск каждой из их функций в отдельности).

  • Некоторые пакеты используют .onLoad слишком свободно, делая вещи, которые не являются строго необходимыми и / или имеют ненужный побочный эффект.Для этого вы всегда можете написать такую ​​функцию, как load_deppkgs_silently(updatesearchpath=TRUE), которую можно вызывать вручную или при загрузке при наличии опции.(Я думаю о ваших конечных пользователях здесь, я большой поклонник обеспечения гибкости и способности не загружать вещи, которые они делают.)

...