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