2011-08-01 4 views
12

J'ai un paquet avec plein de fonctions diverses (voir What to do with imperfect-but-useful functions?). Parce que les fonctions ne sont pas particulièrement liées, elles dépendent d'un tas d'autres paquets. Souvent, il n'y aura qu'une seule fonction dans le paquet entier qui utilise un autre paquet. Pourtant, si j'utilise Imports, Suggests, ou Depends dans le fichier DESCRIPTION, la liste complète des paquets sera chargée chaque fois que mon paquet est chargé, même si très peu d'entre eux sont requis par un utilisateur donné.Charger un paquet seulement si nécessaire dans le paquet R

Est-il possible de charger les dépendances uniquement lorsqu'une fonction particulière est utilisée? Je pourrais mettre un appel à library() à l'intérieur de la fonction eux-mêmes, mais cela semble être une mauvaise pratique, car il ne dit rien au système de gestion de paquets et donc l'utilisateur peut ne pas l'avoir installé.

Répondre

15

Vous pouvez utiliser Suggests, et dans la fonction qui nécessite le package, vous pouvez ajouter du code au package require() et, s'il n'est pas disponible, envoyer une erreur. Un exemple que je connais, le paquet végétalien, a, dans sa description

Depends: permute 
Suggests: MASS, mgcv, lattice, cluster, scatterplot3d, rgl, tcltk 

et sur le chargement du paquet nous avons:

R> require(vegan) 
Loading required package: vegan 
Loading required package: permute 
This is vegan 1.90-0 

et sessionInfo() rapports qu'aucun des paquets proposés n'a pas encore été etc chargé/joint:

R> sessionInfo() 
R version 2.13.1 Patched (2011-07-29 r56550) 
Platform: x86_64-unknown-linux-gnu (64-bit) 

locale: 
[1] LC_CTYPE=en_GB.utf8  LC_NUMERIC=C    
[3] LC_TIME=en_GB.utf8  LC_COLLATE=en_GB.utf8  
[5] LC_MONETARY=C    LC_MESSAGES=en_GB.utf8 
[7] LC_PAPER=en_GB.utf8  LC_NAME=C     
[9] LC_ADDRESS=C    LC_TELEPHONE=C   
[11] LC_MEASUREMENT=en_GB.utf8 LC_IDENTIFICATION=C  

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] vegan_1.90-0 permute_0.5-0 

loaded via a namespace (and not attached): 
[1] tools_2.13.1 
+0

C'est exactement ce que je cherchais. Merci. –

+4

+1 cette stratégie est probablement la plus appropriée pour un paquetage misc: les paquets 'Suggested 'n'ont pas besoin d'être installés pour installer votre paquet. Pour un package misc qui peut être un grand avantage. Par exemple. les utilisateurs peuvent utiliser la partie non-végétalienne du végétalien même si le ggl ne peut pas être installé sur leur machine. Seules les fonctions d'utilisation ne sont pas disponibles dans ce cas. – cbeleites

+0

@cbeleites C'est la raison pour laquelle Jari Oksanen (développeur vegan principal) a choisi d'utiliser Suggests pour les paquets supplémentaires que nous utilisons. –

14

en général, j'essaie d'éviter d'utiliser require() dans des emballages. Comme une suggestion, travailler avec un espace de noms (ce n'est pas difficile) et utiliser Imports: les paquets mentionnés ne sont pas chargés. Vous pouvez importer qu'une seule fonction d'un autre paquet par:

  • en utilisant importFrom déclaration dans le fichier d'espace de noms. importFrom(foo, x, y) indique que les fonctions x et y du paquet foo doivent être importées.
  • en utilisant l'opérateur double-colon dans votre code: foo::bar importe la fonction bar du package foo. par exemple. plyr::ddply(...) auront accès à la fonction ddply sans le paquet est chargé
  • ou l'opérateur du côlon triple en cas d'objets qui ne sont pas exportés (foo:::bar)

Dans les trois cas, les colis doivent être mentionnés dans les importations. Voir aussi le chapitre 1.6 pertinent et d'autres dans Writing R Extensions.

EDIT: Comme l'a souligné @Gavin, tout cela ne fonctionne que lors de l'importation à partir d'un paquet avec un propre espace de noms apparemment. A partir de la version suivante de R (2.14?), Tous les paquets doivent avoir un espace de nommage.

+2

+1 Cela suppose qu'un paquet a un NAMESPACE - beaucoup ne le font pas maintenant, mais tout le sera à partir de la prochaine version majeure de R. –

+0

Voir aussi la discussion ici http: //chat.stackoverflow.com/transcript/message/1143070 # 1143070 –

+0

@Gavin Thx pour le signaler. Mise à jour de la réponse –