84 votes

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

Lorsque je charge un paquet, j'obtiens 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 ?

119voto

Richie Cotton Points 35365

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

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

R va regarder à travers le search pour trouver des fonctions, et utilisera la première qu'il trouvera.

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 paquetage 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 de testthat ne sont pas accessibles de la manière habituelle, c'est-à-dire qu'ils ont été masqué .

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

Vous pouvez fournir explicitement un nom de paquet lorsque vous appelez une fonction, en utilisant l'opérateur double deux points, :: . Par exemple :

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

Comment supprimer le message ?

Si vous êtes au courant du conflit de noms de fonctions et que vous ne voulez pas le revoir, vous pouvez supprimer le message en passant la commande warn.conflicts = FALSE à library .

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

Vous pouvez également supprimer le message avec suppressPackageStartupMessages :

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

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

Si vous avez modifié certaines des options de configuration de démarrage de R (cf. ?Startup ), il se peut que le comportement de masquage des fonctions soit différent de celui auquel vous pourriez vous attendre. L'ordre précis dans lequel les choses se produisent, tel qu'il est défini dans le document ?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 sourcés, seul le paquet de base est utilisé. paquetage de base est chargé, donc les objets des autres paquetages doivent être doivent être référencés par exemple par utils::dump.frames ou après avoir explicitement chargé le concerné.

Ce qui implique que lorsque des paquets tiers sont chargés via des fichiers tels que .Rprofile vous pouvez voir les fonctions de ces paquets masquées par celles des paquets par défaut comme stats et non l'inverse, si vous avez chargé le paquetage tiers après que la procédure de démarrage de R soit terminée.

Comment lister toutes les fonctions masquées ?

Tout d'abord, obtenez un vecteur de caractères de tous les environnements sur le chemin de recherche. Par commodité, nous nommerons 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 ceci 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)
)

Trouvez les cas où l'objet apparaît plus d'une fois.

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

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

Comment éviter les problèmes de conflits de noms ?

Le site conflicted génère une erreur avec un message d'erreur utile lorsque vous essayez d'utiliser une variable dont le nom est ambigu.

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

0 votes

Et si la bibliothèque masquait un objet du paquet "base", par exemple Hmisc::units ? Je dois le placer au début du chemin de recherche pour l'utiliser comme ceci : units(df$age)<-'y' . Existe-t-il une méthode pour cela ?

0 votes

Existe-t-il un moyen de connaître tous les masquages qui ont lieu à un moment donné ?

1 votes

@AdamRyczkowski Utiliser base::units() comme vous le feriez avec n'importe quel autre paquet.

1voto

ahmed jou Points 1

J'ai le même problème. Je l'évite avec remove.packages("Package making this confusion") et ça marche. Dans mon cas, je n'ai pas besoin du deuxième paquet, ce n'est donc pas une très bonne idée.

0voto

Il ne s'agit pas d'une réponse aux questions posées ici, mais d'une suggestion et d'une idée pour les développeurs R. Veuillez prendre l'une ou l'autre des mesures suivantes pour éviter l'apparition des problèmes posés ici.

  1. Il doit y avoir une liste des paquets et des fonctions qu'ils contiennent. Le développeur peut voir la liste et donner un nom à ses fonctions afin qu'il n'y ait pas de conflit avec d'autres. OU, alternativement
  2. Le logiciel R doit automatiquement attribuer une valeur alphanumérique unique, par exemple <fonction-première lettre du paquet concerné-valeurs numériques, à ces noms de fonctions, ajoutés ultérieurement. Pour illustrer, supposons qu'une fonction "fun" existe déjà dans le paquet "pak" ; si le même nom "fun" est ajouté ultérieurement par un autre paquet "pak1", alors le "fun" ajouté ultérieurement doit automatiquement prendre le nouveau nom "fun_1" lors de l'installation du paquet "pak1".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X