“The following object is masked from 'package:xxx'” 是什么意思?

What does "The following object is masked from 'package:xxx'" mean?

提问人:Richie Cotton 提问时间:8/25/2016 最后编辑:smciRichie Cotton 更新时间:11/3/2022 访问量:235490

问:

当我加载一个包时,我收到一条消息,指出:

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

例如,如果我加载 testthat then 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

此消息是什么意思,我该如何防止它?

包括 R-FAQ

评论


答:

144赞 7 revs, 3 users 88%Richie Cotton #1

该消息意味着两个包都具有相同名称的函数。在这种特殊情况下,and 包包含五个同名的函数。testthatassertive

当两个函数具有相同的名称时,调用哪一个函数?

R 将浏览搜索路径以查找函数,并将使用它找到的第一个函数。

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"

在本例中,由于是在 之后加载的,因此它出现在搜索路径的前面,因此将使用该包中的函数。assertivetestthat

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(testthat)
library(assertive, warn.conflicts = FALSE)
# No output this time

或者,使用 suppressPackageStartupMessages 禁止显示消息:

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

R 的启动过程对函数掩码的影响

如果更改了某些 R 的启动配置选项(请参阅),则可能会遇到与预期不同的函数屏蔽行为。事情发生的确切顺序应该可以解开大多数谜团。?Startup?Startup

例如,那里的文档说:

请注意,当站点和用户配置文件仅来源于 基础包已加载,因此其他包中的对象需要 例如由 utils::d ump.frames 引用或在显式加载 有关包裹。

这意味着,当您在 R 的启动过程完成后加载第三方包时,您可能会看到这些包中的函数被默认包(如 stats)中的函数屏蔽,而不是相反。.Rprofile

如何列出所有屏蔽功能?

首先,获取搜索路径上所有环境的字符向量。为方便起见,我们将使用自己的值命名此向量的每个元素。

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)

要测试这一点,请尝试加载一些具有已知冲突的软件包(例如,HmiscAnnotationDbi)。

如何防止名称冲突错误?

每当您尝试使用名称不明确的变量时,包都会引发错误并显示有用的错误消息。conflicted

library(conflicted)
library(Hmisc)
units
## Error: units found in 2 packages. You must indicate which one you want with ::
##  * Hmisc::units
##  * base::units

评论

0赞 Adam Ryczkowski 5/22/2017
如果库从“base”包中屏蔽了一个对象,比如?我需要把它放在搜索路径的开头才能像这样使用它:.有没有办法呢?Hmisc::unitsunits(df$age)<-'y'
0赞 Johannes Wentu 1/16/2018
有没有办法知道在某个时间发生的所有掩蔽?
1赞 Richie Cotton 1/18/2018
@AdamRyczkowski 使用 ,就像使用任何其他包一样。base::units()
0赞 Richie Cotton 1/18/2018
@JohannesWentu我已经更新了我的答案来解释如何做到这一点。
2赞 aosmith 8/4/2018
对于这种情况,包冲突也可能很有用。
0赞 ahmed jou 8/18/2020 #2

我有同样的问题。我避免了它,它起作用了。就我而言,我不需要第二个包,所以这不是一个好主意。remove.packages("Package making this confusion")