1. ホーム
  2. r

[解決済み】「次のオブジェクトは 'package:xxx' からマスクされています」とはどういう意味ですか?

2022-01-29 16:13:53

質問

パッケージを読み込むと、以下のようなメッセージが表示されます。

"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

このメッセージの意味と防止策について教えてください。

解決方法は?

このメッセージは、両方のパッケージが同じ名前の関数を持っていることを意味します。この特定のケースでは testthatassertive パッケージには、同じ名前の関数が5つ含まれています。

2つの関数が同じ名前だったとき、どちらが呼ばれるか?

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 のようなデフォルトパッケージの関数で覆い隠されることがあります。 スタッツ もし、Rのスタートアップが完了した後にサードパーティパッケージをロードした場合、その逆ではなく、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