Was bedeutet "Das folgende Objekt ist aus 'Paket maskiert: xxx'"?

74

Wenn ich ein Paket lade, erhalte ich die folgende Meldung:

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

Wenn ich testthatdann beispielsweise lade assertive, erhalte ich Folgendes:

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

Was bedeutet diese Nachricht und wie verhindere ich sie?

Richie Cotton
quelle

Antworten:

101

Die Nachricht bedeutet, dass beide Pakete Funktionen mit demselben Namen haben. In diesem speziellen Fall enthalten die Pakete testthatund assertivefünf Funktionen mit demselben Namen.

Wenn zwei Funktionen den gleichen Namen haben, welche wird aufgerufen?

R durchsucht den searchPfad nach Funktionen und verwendet die erste gefundene.

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"

In diesem Fall wird es, da assertivees danach geladen wurde testthat, früher im Suchpfad angezeigt, sodass die Funktionen in diesem Paket verwendet werden.

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>

Die Funktionen in testthatsind nicht auf die übliche Weise zugänglich. das heißt, sie wurden maskiert .

Was ist, wenn ich eine der maskierten Funktionen verwenden möchte?

Sie können einen Paketnamen explizit angeben, wenn Sie eine Funktion mit dem Doppelpunkt-Operator aufrufen ::. Zum Beispiel:

testthat::is_true
## function () 
## {
##     function(x) expect_true(x)
## }
## <environment: namespace:testthat>

Wie unterdrücke ich die Nachricht?

Wenn Sie über den Funktionsnamenkonflikt Bescheid wissen und ihn nicht mehr sehen möchten, können Sie die Nachricht unterdrücken, indem Sie warn.conflicts = FALSEan übergeben library.

library(testthat)
library(assertive, warn.conflicts = FALSE)
# No output this time

Alternativ können Sie die Nachricht unterdrücken mit suppressPackageStartupMessages:

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

Einfluss der Startprozeduren von R auf die Funktionsmaskierung

Wenn Sie einige der Startkonfigurationsoptionen von R geändert haben (siehe ?Startup), tritt möglicherweise ein anderes Funktionsmaskierungsverhalten auf als erwartet. Die genaue Reihenfolge, in der die Dinge wie geplant geschehen, ?Startupsollte die meisten Rätsel lösen.

In der Dokumentation heißt es beispielsweise:

Beachten Sie, dass beim Quellen der Site- und Benutzerprofildateien nur das Basispaket geladen wird. Daher müssen Objekte in anderen Paketen beispielsweise von utils :: dump.frames oder nach dem expliziten Laden des betreffenden Pakets referenziert werden.

Dies bedeutet, dass beim Laden .Rprofilevon Paketen von Drittanbietern über Dateien wie diese möglicherweise Funktionen von Paketen angezeigt werden , die von denen in Standardpaketen wie Statistiken maskiert sind , und nicht umgekehrt, wenn Sie das Paket von Drittanbietern nach Abschluss des Startvorgangs von R geladen haben.

Wie liste ich alle maskierten Funktionen auf?

Holen Sie sich zunächst einen Zeichenvektor aller Umgebungen auf dem Suchpfad. Der Einfachheit halber benennen wir jedes Element dieses Vektors mit einem eigenen Wert.

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

Rufen Sie für jede Umgebung die exportierten Funktionen (und andere Variablen) ab.

fns <- lapply(envs, ls)

Verwandeln Sie dies in einen Datenrahmen für die einfache Verwendung mit dplyr.

fns_by_env <- data_frame(
  env = rep.int(names(fns), lengths(fns)),
  fn  = unlist(fns)
)

Suchen Sie nach Fällen, in denen das Objekt mehrmals angezeigt wird.

fns_by_env %>% 
  group_by(fn) %>% 
  tally() %>% 
  filter(n > 1) %>% 
  inner_join(fns_by_env)

Um dies zu testen, versuchen , einige Pakete mit bekannten Konflikten Laden (zB Hmisc, AnnotationDbi).

Wie verhindere ich Namenskonfliktfehler?

Das conflictedPaket gibt einen Fehler mit einer hilfreichen Fehlermeldung aus, wenn Sie versuchen, eine Variable mit einem mehrdeutigen Namen zu verwenden.

library(conflicted)
library(Hmisc)
units
## Error: units found in 2 packages. You must indicate which one you want with ::
##  * Hmisc::units
##  * base::units
Richie Cotton
quelle
Was passiert, wenn die Bibliothek ein Objekt aus dem Basispaket maskiert Hmisc::units? Ich muss es an den Anfang des Suchpfads setzen, um es so zu verwenden : units(df$age)<-'y'. Gibt es dafür eine Methode?
Adam Ryczkowski
Gibt es eine Möglichkeit, alle Maskierungen zu kennen, die zu einem bestimmten Zeitpunkt stattfinden?
Johannes Wentu
1
@AdamRyczkowski Verwenden Sie base::units(), wie Sie es mit jedem anderen Paket tun würden.
Richie Cotton
@JohannesWentu Ich habe meine Antwort aktualisiert, um zu erklären, wie das geht.
Richie Cotton
2
Paketkonflikte können in dieser Situation ebenfalls hilfreich sein.
Aosmith
0

Ich habe das gleiche Problem. Ich vermeide es mit remove.packages("Package making this confusion")und es funktioniert. In meinem Fall brauche ich das zweite Paket nicht, das ist also keine sehr gute Idee.

ahmed jou
quelle