Что означает «Следующий объект замаскирован из пакета: xxx»?

Когда я загружаю пакет, я получаю сообщение о том, что:

"The following object is masked from 'package:xxx'

Например, если я загружаю testthat, то assertive, я получаю следующее:

library(testthat)
library(assertive)  
## Attaching package: ‘assertive’
## 
## The following objects are masked from ‘package:testthat’:
## 
##     has_names, is_false, is_less_than, is_null, is_true

Что означает это сообщение и как его предотвратить?


person Richie Cotton    schedule 25.08.2016    source источник


Ответы (3)


Сообщение означает, что оба пакета имеют функции с одинаковыми именами. В данном конкретном случае пакеты testthat и assertive содержат пять функций с одинаковыми именами.

Когда две функции имеют одно и то же имя, какая из них вызывается?

R просматривает путь search для поиска функций и использует первый что находит.

search()
 ##  [1] ".GlobalEnv"        "package:assertive" "package:testthat" 
 ##  [4] "tools:rstudio"     "package:stats"     "package:graphics" 
 ##  [7] "package:grDevices" "package:utils"     "package:datasets" 
 ## [10] "package:methods"   "Autoloads"         "package:base"

В этом случае, поскольку assertive был загружен после testthat, он появится в пути поиска раньше, поэтому будут использоваться функции из этого пакета.

is_true
## function (x, .xname = get_name_in_parent(x)) 
## {
##     x <- coerce_to(x, "logical", .xname)
##     call_and_name(function(x) {
##         ok <- x & !is.na(x)
##         set_cause(ok, ifelse(is.na(x), "missing", "false"))
##     }, x)
## }
<bytecode: 0x0000000004fc9f10>
<environment: namespace:assertive.base>

Функции в testthat недоступны обычным способом; то есть они были замаскированы.

Что делать, если я хочу использовать одну из замаскированных функций?

Вы можете явно указать имя пакета при вызове функции, используя оператор с двойным двоеточием, ::. Например:

testthat::is_true
## function () 
## {
##     function(x) expect_true(x)
## }
## <environment: namespace:testthat>

Как подавить сообщение?

Если вы знаете о конфликте имени функции и не хотите видеть его снова, вы можете подавить сообщение, передав warn.conflicts = FALSE в library.

library(testthat)
library(assertive, warn.conflicts = FALSE)
# No output this time

Либо скройте сообщение с помощью suppressPackageStartupMessages:

library(testthat)
suppressPackageStartupMessages(library(assertive))
# Also no output

Влияние процедур запуска R на маскирование функций

Если вы изменили некоторые параметры конфигурации запуска R (см. ?Startup), вы можете столкнуться с поведением маскирования функций, отличным от ожидаемого. Точный порядок событий, изложенный в ?Startup, должен раскрыть большинство загадок.

Например, в документации там сказано:

Обратите внимание, что при получении файлов сайта и профиля пользователя загружается только базовый пакет, поэтому на объекты в других пакетах необходимо ссылаться, например. utils::dump.frames или после явной загрузки соответствующего пакета.

Это означает, что когда сторонние пакеты загружаются через такие файлы, как .Rprofile, вы можете видеть функции из этих пакетов, замаскированные функциями в пакетах по умолчанию, такими как stats, а не наоборот, если вы загрузили сторонний пакет после R процедура запуска завершена.

Как вывести список всех замаскированных функций?

Во-первых, получите вектор символов всех сред на пути поиска. Для удобства мы назовем каждый элемент этого вектора своим собственным значением.

library(dplyr)
envs <- search() %>% setNames(., .)

Для каждой среды получите экспортированные функции (и другие переменные).

fns <- lapply(envs, ls)

Превратите это в фрейм данных для удобства использования с dplyr.

fns_by_env <- data_frame(
  env = rep.int(names(fns), lengths(fns)),
  fn  = unlist(fns)
)

Найдите случаи, когда объект появляется более одного раза.

fns_by_env %>% 
  group_by(fn) %>% 
  tally() %>% 
  filter(n > 1) %>% 
  inner_join(fns_by_env)

Чтобы проверить это, попробуйте загрузить некоторые пакеты с известными конфликтами (например, Hmisc, < a href="https://www.bioconductor.org/packages/release/bioc/html/AnnotationDbi.html" rel="noreferrer">AnnotationDbi).

Как предотвратить ошибки конфликта имен?

Пакет conflicted выдает ошибку с полезным сообщением об ошибке всякий раз, когда вы пытаетесь использовать переменную с неоднозначным именем.

library(conflicted)
library(Hmisc)
units
## Error: units found in 2 packages. You must indicate which one you want with ::
##  * Hmisc::units
##  * base::units
person Community    schedule 25.08.2016
comment
Что, если библиотека маскирует объект из «базового» пакета, например Hmisc::units? Мне нужно поместить его в начало пути поиска, чтобы использовать его так: units(df$age)<-'y'. Есть ли способ для этого? - person Adam Ryczkowski; 22.05.2017
comment
Есть ли способ узнать все маскировки, происходящие в определенное время? - person Johannes Wentu; 16.01.2018
comment
@AdamRyczkowski Используйте base::units(), как и любой другой пакет. - person Richie Cotton; 17.01.2018
comment
@JohannesWentu Я обновил свой ответ, чтобы объяснить, как это сделать. - person Richie Cotton; 17.01.2018
comment
Конфликтующий пакет также может быть полезен в этой ситуации. - person aosmith; 03.08.2018

У меня та же проблема. Я избегаю этого с помощью remove.packages("Package making this confusion"), и это работает. В моем случае мне не нужен второй пакет, так что это не очень хорошая идея.

person ahmed jou    schedule 18.08.2020

Это не ответ на поставленные здесь вопросы, а предложение и идея для разработчиков R. Пожалуйста, примите любую из следующих мер, чтобы избежать возникновения проблем, изложенных здесь.

  1. Там должен быть список пакетов и функций. Разработчик может посмотреть список и дать имя своим функциям, чтобы оно не конфликтовало с другими. ИЛИ, альтернативно
  2. Программное обеспечение R должно автоматически назначать уникальное буквенно-цифровое значение, например ‹первая буква функции соответствующих числовых значений пакета, тем именам функций, которые добавляются впоследствии. Для иллюстрации предположим, что функция fun уже существует в пакете pak; тогда, если fun с тем же именем впоследствии добавляется другим пакетом pak1, то последующий добавленный fun должен автоматически получить новое имя fun_1 при установке пакета pak1.
person Hosur Kumaraswamy    schedule 24.06.2021