【问题标题】:What does "The following object is masked from 'package:xxx'" mean?“以下对象被'package:xxx'屏蔽”是什么意思?
【发布时间】:2017-01-01 09:41:09
【问题描述】:

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

"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

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

【问题讨论】:

    标签: r r-faq


    【解决方案1】:

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

    当两个函数同名时,调用哪个函数?

    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 之类的文件加载第 3 方包时,如果您加载了R启动程序完成后的第三方包。

    如何列出所有被屏蔽的函数?

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

    library(dplyr)
    envs <- search() %>% setNames(., .)
    

    对于每个环境,获取导出的函数(和其他变量)。

    fns <- lapply(envs, ls)
    

    将其转换为数据框,以便与 d​​plyr 一起使用。

    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
    

    【讨论】:

    • 如果库从'base'包中屏蔽了一个对象,比如Hmisc::units?我需要把它放在搜索路径的开头才能像这样使用它:units(df$age)&lt;-'y'。有办法吗?
    • 有没有办法知道在某个时间发生的所有掩蔽?
    • @AdamRyczkowski 使用base::units(),就像使用任何其他软件包一样。
    • @JohannesWentu 我已经更新了我的答案来解释如何做到这一点。
    • Package conflicted 在这种情况下也可能有用。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-12
      相关资源
      最近更新 更多