web-dev-qa-db-fra.com

Que signifie "L'objet suivant est masqué à partir de 'package: xxx'"?

Lorsque je charge un paquet, je reçois un message indiquant que:

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

Par exemple, si je charge testthat puis assertive , j'obtiens ce qui suit :

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

Que signifie ce message et comment puis-je l'éviter?

50
Richie Cotton

Le message signifie que les deux packages ont des fonctions portant les mêmes noms. Dans ce cas particulier, les packages testthat et assertive contiennent cinq fonctions portant le même nom.

Lorsque deux fonctions portent le même nom, laquelle est appelée?

R examinera le chemin search pour trouver des fonctions et utilisera le premier.

_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"
_

Dans ce cas, puisque assertive a été chargé après testthat, il apparaît plus tôt dans le chemin de recherche et les fonctions de ce package seront donc utilisées.

_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>
_

Les fonctions dans testthat ne sont pas accessibles de la manière habituelle; c'est-à-dire qu'ils ont été masqués .

Et si je veux utiliser l'une des fonctions masquées?

Vous pouvez explicitement fournir un nom de package lorsque vous appelez une fonction, à l'aide de l'opérateur à deux points, :: . Par exemple:

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

Comment puis-je supprimer le message?

Si vous connaissez le conflit de nom de fonction et que vous ne voulez plus le revoir, vous pouvez supprimer le message en transmettant _warn.conflicts = FALSE_ à library .

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

Sinon, supprimez le message avec suppressPackageStartupMessages :

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

Impact des procédures de démarrage de R sur le masquage de fonction

Si vous avez modifié certaines des options de configuration de démarrage de R (voir _?Startup_), vous risquez de rencontrer un comportement de masquage de fonction différent de celui auquel vous pourriez vous attendre. L'ordre précis dans lequel les choses se passent, comme indiqué dans _?Startup_ devrait résoudre la plupart des mystères.

Par exemple, la documentation indique:

Notez que lorsque les fichiers de site et de profil utilisateur sont générés, seul le package de base est chargé. Par conséquent, les objets d'autres packages doivent être référencés, par exemple. utils :: dump.frames ou après le chargement explicite du paquet concerné.

Ce qui implique que lorsque des packages tiers sont chargés via des fichiers tels que _.Rprofile_, vous pouvez voir les fonctions de ces packages masquées par celles des packages par défaut tels que stats , plutôt que l’inverse, si vous avez chargé le package tiers après la fin de la procédure de démarrage de R.

Comment lister toutes les fonctions masquées?

Commencez par obtenir un vecteur de caractères de tous les environnements du chemin de recherche. Pour plus de commodité, nous allons nommer chaque élément de ce vecteur avec sa propre valeur.

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

Pour chaque environnement, obtenez les fonctions exportées (et autres variables).

_fns <- lapply(envs, ls)
_

Transformez cela en un cadre de données, pour une utilisation facile avec dplyr.

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

Recherchez les cas où l'objet apparaît plusieurs fois.

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

Pour tester cela, essayez de charger certains packages avec des conflits connus (par exemple, Hmisc , AnnotationDbi ).

Comment puis-je prévenir les bogues de conflit de noms?

Le package conflicted génère une erreur avec un message d'erreur utile chaque fois que vous essayez d'utiliser une variable avec un nom ambigu.

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