Wat betekent “Het volgende object is gemaskeerd uit ‘package:xxx'”?

Als ik een pakket laad, krijg ik een bericht waarin staat dat:

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

Als ik bijvoorbeeld testthatlaad, dan assertive, krijg ik het volgende:

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

Wat betekent dit bericht en hoe voorkom ik het?


Antwoord 1, autoriteit 100%

Het bericht betekent dat beide pakketten functies hebben met dezelfde namen. In dit specifieke geval bevatten de pakketten testthaten assertivevijf functies met dezelfde naam.

Als twee functies dezelfde naam hebben, welke wordt dan aangeroepen?

R zoekt door het search-pad om functies te vinden, en zal de eerste gebruiken die het vindt.

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 dit geval, aangezien assertivewerd geladen na testthat, verschijnt het eerder in het zoekpad, dus de functies in dat pakket zullen worden gebruikt.

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>

De functies in testthatzijn niet op de gebruikelijke manier toegankelijk; dat wil zeggen, ze zijn gemaskeerd.

Wat als ik een van de gemaskeerde functies wil gebruiken?

U kunt expliciet een pakketnaam opgeven wanneer u een functie aanroept, met behulp van de dubbele dubbele punt-operator, ::. Bijvoorbeeld:

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

Hoe kan ik het bericht onderdrukken?

Als je weet van de functienaamclash en deze niet meer wilt zien, kun je het bericht onderdrukken door warn.conflicts = FALSEdoor te geven aan library.

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

U kunt het bericht ook onderdrukken met suppressPackageStartupMessages:

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

Impact van de opstartprocedures van R op functiemaskering

Als je een aantal opstartconfiguratie-opties van R hebt gewijzigd (zie ?Startup), kan het zijn dat je een ander functiemaskeringsgedrag ervaart dan je zou verwachten. De precieze volgorde waarin dingen gebeuren zoals uiteengezet in ?Startupzou de meeste mysteries moeten oplossen.

Bijvoorbeeld, de documentatie daar zegt:

Merk op dat wanneer de site- en gebruikersprofielbestanden alleen afkomstig zijn van de
basispakket is geladen, dus objecten in andere pakketten moeten
genoemd door bijv. utils::dump.frames of na het expliciet laden van de
betrokken pakket.

Wat inhoudt dat wanneer pakketten van derden worden geladen via bestanden zoals .Rprofile, u functies van die pakketten mogelijk gemaskeerd ziet door die in standaardpakketten zoals stats, in plaats van de omgekeerd, als u het pakket van derden hebt geladen nadat de opstartprocedure van R is voltooid.

Hoe vermeld ik alle gemaskeerde functies?

Verkrijg eerst een karaktervector van alle omgevingen in het zoekpad. Voor het gemak geven we elk element van deze vector een naam met zijn eigen waarde.

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

Verkrijg voor elke omgeving de geëxporteerde functies (en andere variabelen).

fns <- lapply(envs, ls)

Verander dit in een dataframe, voor eenvoudig gebruik met dplyr.

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

Vind gevallen waarin het object meer dan één keer verschijnt.

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

Probeer dit te testen, probeer wat pakketten met bekende conflicten (bijv. Hmisc, AnnotationDbi).

Hoe voorkomen ik de naam conflictbugs?

De conflictedPackage gooit een foutmelding met een handig foutbericht, telkens wanneer u een variabele probeert te gebruiken met een dubbelzinnige naam.

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

Antwoord 2

Ik heb hetzelfde probleem. Ik vermijd het met remove.packages("Package making this confusion")en het werkt. In mijn geval heb ik het tweede pakket niet nodig, dus dat is geen heel goed idee.


Antwoord 3

Het is geen antwoord op de hierin geposulteerde problemen, maar een suggestie en idee voor R-ontwikkelaars. Neem een ​​van de volgende maatregelen om het hierin te voorkomen dat de problemen is voorgelegd.

  1. Er moet een lijst met pakketten en functies daarin zijn. De ontwikkelaar kan de lijst zien en de naam geven aan hun functies, zodat het niet conflicteert met anderen.
    Of, alternatief
  2. R-software moet automatisch een unieke alfanumerieke waarde toewijzen, bijvoorbeeld <functie-eerste letter van de betreffende pakketnumerieke waarden, aan die functienamen, die vervolgens worden toegevoegd. Ter illustratie, aangenomen dat er al een functie “fun” bestaat in pakket “pak”; als dan dezelfde naam “fun” later wordt toegevoegd door een ander pakket “pak1”, dan moet de daarna toegevoegde “fun” automatisch de nieuwe naam “fun_1” krijgen bij het installeren van het pakket “pak1”.

Other episodes