R “以下对象被‘package:xxx’屏蔽”是什么意思?

R “以下对象被‘package:xxx’屏蔽”是什么意思?,r,r-faq,R,R Faq,当我加载一个包时,我会收到一条消息,说明: "The following object is masked from 'package:xxx' 例如,如果加载,则会得到以下结果: library(testthat) library(assertive) ## Attaching package: ‘assertive’ ## ## The following objects are masked from ‘package:testthat’: ## ## has_names

当我加载一个包时,我会收到一条消息,说明:

"The following object is masked from 'package:xxx'
例如,如果加载,则会得到以下结果:

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

此消息的含义是什么?我如何防止它?

此消息表示两个软件包的函数名称相同。在本例中,testthat和断言包包含五个同名函数

当两个函数同名时,调用哪一个? 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"
在本例中,由于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>
如何抑制该消息? 如果您知道函数名冲突,并且不想再次看到它,可以通过将warn.conflicts=FALSE传递给来抑制该消息

或者,使用以下命令抑制消息:

R的启动程序对功能屏蔽的影响 如果您更改了R的一些启动配置选项,请参阅?启动,您可能会遇到与预期不同的函数屏蔽行为。按照《初创企业》中所述的事情发生的精确顺序,应该可以解开大多数谜团

例如,那里的文档说明:

请注意,当站点和用户配置文件来源仅为 已加载基本包,因此需要加载其他包中的对象 例如,通过utils::dump.frames或在显式加载 有关的一揽子计划

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

如何列出所有屏蔽函数? 首先,获取搜索路径上所有环境的特征向量。为了方便起见,我们将用它自己的值命名这个向量的每个元素

library(dplyr)
envs <- search() %>% setNames(., .)
要测试这一点,请尝试加载一些具有已知冲突的包,例如

如何防止名称冲突bug? 每当您尝试使用名称不明确的变量时,冲突包就会抛出一个错误,并显示一条有用的错误消息

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

我也有同样的问题。我使用remove.packagesPackage避免了这种混淆,它可以正常工作。在我的例子中,我不需要第二个包,所以这不是一个好主意。

如果库从“基本”包(如Hmisc::units)屏蔽一个对象,该怎么办?我需要把它放在搜索路径的开头,这样使用它:unitsdf$age有没有办法知道在某个时间发生的所有屏蔽?@AdamRyczkowski使用base::units,就像你使用任何其他包一样。@JohannesWentu我更新了我的答案来解释如何做到这一点。对于这种情况也可能有用。
library(testthat)
suppressPackageStartupMessages(library(assertive))
# Also no output
library(dplyr)
envs <- search() %>% setNames(., .)
fns <- lapply(envs, ls)
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)
library(conflicted)
library(Hmisc)
units
## Error: units found in 2 packages. You must indicate which one you want with ::
##  * Hmisc::units
##  * base::units