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