Что означает "следующий объект маскируется из 'package: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

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

1 ответов


сообщение означает, что оба пакета имеют функции с одинаковыми именами. В этом конкретном случае 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 to 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.рамки или после явной загрузки пакет обеспокоенный.

что означает, что при загрузке сторонних пакетов через файлы, такие как .Rprofile вы можете видеть функции из этих пакетов, замаскированных теми, кто в пакетах по умолчанию, как статистика, а не наоборот, если вы загрузили сторонний пакет после завершения процедуры запуска 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, 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