Une manière élégante de vérifier les paquets manquants et de les installer?

Je semble partager beaucoup de code avec les coauteurs ces jours-ci. Beaucoup d’entre eux sont des utilisateurs débutants / intermédiaires et ne réalisent pas qu’ils doivent installer des packages qu’ils n’ont pas déjà.

Existe-t-il un moyen élégant d’appeler installed.packages() , comparez-le à ceux que je charge et installez s’il manque?

Oui. Si vous avez votre liste de paquets, comparez-la à la sortie de installed.packages()[,"Package"] et installez les paquets manquants. Quelque chose comme ça:

 list.of.packages <- c("ggplot2", "Rcpp") new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])] if(length(new.packages)) install.packages(new.packages) 

Autrement:

Si vous placez votre code dans un package et en faites des dépendances, elles seront automatiquement installées lors de l’installation de votre package.

Dason K. et moi avons le paquet pacman qui peut le faire bien. La fonction p_load du paquet le fait. La première ligne est juste pour s’assurer que pacman est installé.

 if (!require("pacman")) install.packages("pacman") pacman::p_load(package1, package2, package_n) 

Vous pouvez simplement utiliser la valeur de retour de require :

 if(!require(somepackage)){ install.packages("somepackage") library(somepackage) } 

J’utilise la library après l’installation, car elle lancera une exception si l’installation n’a pas réussi ou si le paquet ne peut pas être chargé pour une autre raison. Vous rendez cela plus robuste et réutilisable:

 dynamic_require <- function(package){ if(eval(parse(text=paste("require(",package,")")))) return True install.packages(package) return eval(parse(text=paste("require(",package,")"))) } 

L'inconvénient de cette méthode est que vous devez transmettre le nom du package entre guillemets, ce que vous ne faites pas pour le vrai require .

Bien que la réponse de Shane soit vraiment bonne, pour l’un de mes projets, je devais supprimer automatiquement les messages de sortie, les avertissements et les paquets d’ installation . J’ai enfin réussi à obtenir ce script:

 InstalledPackage <- function(package) { available <- suppressMessages(suppressWarnings(sapply(package, require, quietly = TRUE, character.only = TRUE, warn.conflicts = FALSE))) missing <- package[!available] if (length(missing) > 0) return(FALSE) return(TRUE) } CRANChoosen <- function() { return(getOption("repos")["CRAN"] != "@CRAN@") } UsePackage <- function(package, defaultCRANmirror = "http://cran.at.r-project.org") { if(!InstalledPackage(package)) { if(!CRANChoosen()) { chooseCRANmirror() if(!CRANChoosen()) { options(repos = c(CRAN = defaultCRANmirror)) } } suppressMessages(suppressWarnings(install.packages(package))) if(!InstalledPackage(package)) return(FALSE) } return(TRUE) } 

Utilisation:

 libraries <- c("ReadImages", "ggplot2") for(library in libraries) { if(!UsePackage(library)) { stop("Error!", library) } } 

Cette solution prendra un vecteur de caractères de noms de paquets et tentera de les charger ou de les installer si le chargement échoue. Il repose sur le comportement de retour de require pour faire cela car …

require retourner (de manière invisible) une indication logique indiquant si le package requirejs est disponible

Par conséquent, nous pouvons simplement voir si nous avons été en mesure de charger le package requirejs et sinon, installez-le avec des dépendances. Donc, étant donné un vecteur de caractères des paquets que vous souhaitez charger …

 foo <- function(x){ for( i in x ){ # require returns TRUE invisibly if it was able to load package if( ! require( i , character.only = TRUE ) ){ # If package was not able to be loaded then re-install install.packages( i , dependencies = TRUE ) # Load package after installing require( i , character.only = TRUE ) } } } # Then try/install packages... foo( c("ggplot2" , "reshape2" , "data.table" ) ) 
 if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2') 

“ggplot2” est le paquet. Il vérifie si le paquet est installé, sinon il l’installe. Il charge ensuite le package quelle que soit la twig.

Un grand nombre des réponses ci-dessus (et des doublons de cette question) reposent sur des packages installed.packages ce qui est une mauvaise forme. De la documentation:

Cela peut être lent lorsque des milliers de packages sont installés, donc ne l’utilisez pas pour savoir si un package nommé est installé (utilisez system.file ou find.package) ni pour savoir si un package est utilisable (appel requirejs et vérifiez le valeur de retour) ni de trouver les détails d’un petit nombre de paquets (utilisez packageDescription). Il doit lire plusieurs fichiers par paquet installé, ce qui sera lent sous Windows et sur certains systèmes de fichiers montés en réseau.

Donc, une meilleure approche est d’essayer de charger le paquet en utilisant require et et d’installer si le chargement échoue ( require retournera FALSE s’il n’est pas trouvé). Je préfère cette mise en œuvre:

 using<-function(...) { libs<-unlist(list(...)) req<-unlist(lapply(libs,require,character.only=TRUE)) need<-libs[req==FALSE] if(length(need)>0){ install.packages(need) lapply(need,require,character.only=TRUE) } } 

qui peut être utilisé comme ceci:

 using("RCurl","ggplot2","jsonlite","magrittr") 

De cette façon, il charge tous les paquets, puis retourne et installe tous les paquets manquants (ce qui, si vous le souhaitez, est un endroit pratique pour insérer une invite vous demandant si l’utilisateur souhaite installer les paquets). Au lieu d’appeler séparément install.packages pour chaque paquet, il ne passe qu’une fois le vecteur entier des paquets désinstallés.

Voici la même fonction mais avec une boîte de dialog Windows qui demande si l’utilisateur veut installer les paquets manquants

 using<-function(...) { libs<-unlist(list(...)) req<-unlist(lapply(libs,require,character.only=TRUE)) need<-libs[req==FALSE] n<-length(need) if(n>0){ libsmsg<-if(n>2) paste(paste(need[1:(n-1)],collapse=", "),",",sep="") else need[1] print(libsmsg) if(n>1){ libsmsg<-paste(libsmsg," and ", need[n],sep="") } libsmsg<-paste("The following packages could not be found: ",libsmsg,"\n\r\n\rInstall missing packages?",collapse="") if(winDialog(type = c("yesno"), libsmsg)=="YES"){ install.packages(need) lapply(need,require,character.only=TRUE) } } } 
 # List of packages for session .packages = c("ggplot2", "plyr", "rms") # Install CRAN packages (if not already installed) .inst <- .packages %in% installed.packages() if(length(.packages[!.inst]) > 0) install.packages(.packages[!.inst]) # Load packages into session lapply(.packages, require, character.only=TRUE) 

Sûr.

Vous devez comparer les «packages installés» avec les «packages souhaités». C’est très proche de ce que je fais avec CRANberries car je dois comparer les «paquets connus stockés» avec les «paquets actuellement connus» pour déterminer les paquets nouveaux et / ou mis à jour.

Alors, faites quelque chose comme

 AP <- available.packages(contrib.url(repos[i,"url"])) # available t repos[i] 

pour obtenir tous les paquets connus, appel simulaire pour les paquets actuellement installés et le comparer à un ensemble donné de paquets cibles.

C’est le but du paquetage rbundler : fournir un moyen de contrôler les paquetages installés pour un projet spécifique. À l’heure actuelle, le paquet fonctionne avec la fonctionnalité devtools pour installer des paquets dans le répertoire de votre projet. La fonctionnalité est similaire à celle du bundler de Ruby.

Si votre projet est un package (recommandé), il vous suffit de charger rbundler et de regrouper les packages. La fonction bundle examinera le fichier DESCRIPTION votre package pour déterminer les packages à regrouper.

 library(rbundler) bundle('.', repos="http://cran.us.r-project.org") 

Les paquets seront maintenant installés dans le répertoire .Rbundle.

Si votre projet n’est pas un package, vous pouvez le faire en créant un fichier DESCRIPTION dans le répertoire racine de votre projet avec un champ Depends répertoriant les packages que vous souhaitez installer (avec des informations de version facultatives):

 Depends: ggplot2 (>= 0.9.2), arm, glmnet 

Voici le repository github pour le projet si vous êtes intéressé à consortingbuer: rbundler .

La fonction simple suivante fonctionne comme un charme:

  usePackage<-function(p){ # load a package if installed, else load after installation. # Args: # p: package name in quotes if (!is.element(p, installed.packages()[,1])){ print(paste('Package:',p,'Not found, Installing Now...')) install.packages(p, dep = TRUE)} print(paste('Loading Package :',p)) require(p, character.only = TRUE) } 

(pas le mien, l'a trouvé sur le web il y a quelque temps et l'utilisait depuis. pas sûr de la source originale)

J’utilise la fonction suivante pour installer le paquet si require("") quitte avec le paquet erreur non trouvée. Il interrogera à la fois les référentiels CRAN et Bioconductor pour les paquets manquants.

Adapté de l’œuvre originale de Joshua Wiley, http://r.789695.n4.nabble.com/Install-package-automatically-if-not-there-td2267532.html

 install.packages.auto <- function(x) { x <- as.character(substitute(x)) if(isTRUE(x %in% .packages(all.available=TRUE))) { eval(parse(text = sprintf("require(\"%s\")", x))) } else { #update.packages(ask= FALSE) #update installed packages. eval(parse(text = sprintf("install.packages(\"%s\", dependencies = TRUE)", x))) } if(isTRUE(x %in% .packages(all.available=TRUE))) { eval(parse(text = sprintf("require(\"%s\")", x))) } else { source("http://bioconductor.org/biocLite.R") #biocLite(character(), ask=FALSE) #update installed packages. eval(parse(text = sprintf("biocLite(\"%s\")", x))) eval(parse(text = sprintf("require(\"%s\")", x))) } } 

Exemple:

 install.packages.auto(qvalue) # from bioconductor install.packages.auto(rNMF) # from CRAN 

PS: update.packages(ask = FALSE) & biocLite(character(), ask=FALSE) jour tous les packages installés sur le système. Cela peut prendre beaucoup de temps et considérer cela comme une mise à niveau complète de R qui peut ne pas être garantie tout le temps!

Vous pouvez simplement utiliser la fonction setdiff pour obtenir les packages qui ne sont pas installés, puis les installer. Dans l’exemple ci-dessous, nous vérifions si les ggplot2 et Rcpp sont installés avant de les installer.

 unavailable <- setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages())) install.packages(unavailable) 

Dans une ligne, ce qui précède peut être écrit comme suit:

 install.packages(setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages()))) 

J’ai implémenté la fonction pour installer et charger les packages R requirejs en mode silencieux. L’espoir pourrait aider. Voici le code:

 # Function to Install and Load R Packages Install_And_Load <- function(Required_Packages) { Remaining_Packages <- Required_Packages[!(Required_Packages %in% installed.packages()[,"Package"])]; if(length(Remaining_Packages)) { install.packages(Remaining_Packages); } for(package_name in Required_Packages) { library(package_name,character.only=TRUE,quietly=TRUE); } } # Specify the list of required packages to be installed and load Required_Packages=c("ggplot2", "Rcpp"); # Call the Function Install_And_Load(Required_Packages); 

En ce qui concerne votre objective principal “installer les bibliothèques qu’ils n’ont pas déjà.” Et indépendamment de l’utilisation de “instllaed.packages ()”. La fonction suivante masque la fonction d’origine de require. Il essaie de charger et de vérifier le package nommé “x”, s’il n’est pas installé, installez-le directement, y compris les dépendances; et enfin le charger normalement. vous renommez le nom de la fonction de ‘require’ en ‘library’ pour maintenir l’intégrité. La seule limitation est que les noms de paquets doivent être cités.

 require <- function(x) { if (!base::require(x, character.only = TRUE)) { install.packages(x, dep = TRUE) ; base::require(x, character.only = TRUE) } } 

Ainsi, vous pouvez charger et installer le paquetage à l'ancienne façon de R. require ("ggplot2") ("Rcpp")

Assez basique

 pkgs = c("pacman","data.table") if(length(new.pkgs <- setdiff(pkgs, rownames(installed.packages())))) install.packages(new.pkgs) 

Je pensais que je consortingbuerais celui que j’utilise:

 testin <- function(package){if (!package %in% installed.packages()) install.packages(package)} testin("packagename") 

Utilisez packrat pour que les bibliothèques partagées soient exactement les mêmes et ne modifient pas l’environnement des autres.

Pour ce qui est de l’élégance et des meilleures pratiques, je pense que votre stratégie est fondamentalement différente. le package packrat été conçu pour ces problèmes. Il est développé par RStudio par Hadley Wickham. Au lieu de devoir installer des dépendances et éventuellement déranger quelqu’un, le système de l’environnement packrat utilise son propre répertoire et installe toutes les dépendances pour vos programmes et ne touche pas à l’environnement de quelqu’un.

Packrat est un système de gestion des dépendances pour R.

Les dépendances de paquet R peuvent être frustrantes. Avez-vous déjà eu besoin d’essayer et d’errer pour déterminer les packages R que vous devez installer pour faire fonctionner le code de quelqu’un d’autre, puis de les installer définitivement pour toujours, car vous ne savez plus si vous en avez besoin ? Avez-vous déjà mis à jour un paquet pour que le code fonctionne dans l’un de vos projets, pour constater que le package mis à jour empêche le code d’un autre projet de fonctionner?

Nous avons construit packrat pour résoudre ces problèmes. Utilisez packrat pour rendre vos projets R plus:

  • Isolé: l’installation d’un nouveau package ou d’un package mis à jour pour un projet ne rompt pas vos autres projets et inversement. C’est parce que packrat donne à chaque projet sa propre bibliothèque de paquet privé.
  • Portable: transportez facilement vos projets d’un ordinateur à un autre, même sur différentes plates-formes. Packrat facilite l’installation des packages dont dépend votre projet.
  • Reproductible: Packrat enregistre les versions de package exactes dont vous dépendez et garantit que ces versions exactes sont celles qui s’installent partout où vous allez.

https://rstudio.github.io/packrat/

J’utilise les éléments suivants qui vérifient si le package est installé et si les dépendances sont mises à jour, puis charge le package.

 p<-c('ggplot2','Rcpp') install_package<-function(pack) {if(!(pack %in% row.names(installed.packages()))) { update.packages(ask=F) install.packages(pack,dependencies=T) } require(pack,character.only=TRUE) } for(pack in p) {install_package(pack)} completeFun <- function(data, desiredCols) { completeVec <- complete.cases(data[, desiredCols]) return(data[completeVec, ]) } 

Voici mon code pour cela:

 packages <- c("dplyr", "gridBase", "gridExtra") package_loader <- function(x){ for (i in 1:length(x)){ if (!identical((x[i], installed.packages()[x[i],1])){ install.packages(x[i], dep = TRUE) } else { require(x[i], character.only = TRUE) } } } package_loader(packages) 
  48 lapply_install_and_load <- function (package1, ...) 49 { 50 # 51 # convert arguments to vector 52 # 53 packages <- c(package1, ...) 54 # 55 # check if loaded and installed 56 # 57 loaded <- packages %in% (.packages()) 58 names(loaded) <- packages 59 # 60 installed <- packages %in% rownames(installed.packages()) 61 names(installed) <- packages 62 # 63 # start loop to determine if each package is installed 64 # 65 load_it <- function (p, loaded, installed) 66 { 67 if (loaded[p]) 68 { 69 print(paste(p, "loaded")) 70 } 71 else 72 { 73 print(paste(p, "not loaded")) 74 if (installed[p]) 75 { 76 print(paste(p, "installed")) 77 do.call("library", list(p)) 78 } 79 else 80 { 81 print(paste(p, "not installed")) 82 install.packages(p) 83 do.call("library", list(p)) 84 } 85 } 86 } 87 # 88 lapply(packages, load_it, loaded, installed) 89 } 
 library <- function(x){ x = toString(substitute(x)) if(!require(x,character.only=TRUE)){ install.packages(x) base::library(x,character.only=TRUE) }} 

Cela fonctionne avec des noms de paquets non cotés et est assez élégant (voir la réponse de GeoObserver)

 source("https://bioconductor.org/biocLite.R") if (!require("ggsci")) biocLite("ggsci") 

Dans mon cas, je voulais une ligne unique que je pourrais exécuter à partir de la ligne de commande (en fait via un Makefile). Voici un exemple d’installation de “VGAM” et “feather” s’ils ne sont pas déjà installés:

 R -e 'for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")' 

De l’intérieur, il ne s’agirait que de:

 for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org") 

Il n’y a rien ici au-delà des solutions précédentes sauf que:

  • Je le garde sur une seule ligne
  • Je code le paramètre repos (pour éviter que des popups sur le miroir ne soient utilisés)
  • Je ne me donne pas la peine de définir une fonction à utiliser ailleurs

Notez également l’important character.only=TRUE (sans lui, le require essaierait de charger le package p ).

En utilisant la famille lapply et l’approche de la fonction anonyme, vous pouvez:

  lib.names <- c("plyr", "psych", "tm") sapply(lib.names, function(x) require(x, character.only = TRUE) || {install.packages(x); require(x, character.only = TRUE)}) plyr psych tm TRUE TRUE TRUE 
  1. Essayez de joindre tous les packages listés.
  2. Installer manquant seulement (en utilisant || évaluation paresseuse).
  3. Chargez ceux qui manquaient / nouvellement installés.
  4. Imprime un résumé total (TRUE / FALSE) de l’état de chargement de chaque paquet.

essaye ça:

 if (!require(MyDesiredLibrary)) { install.packages("MyDesiredLibrary") }