questions - ¿Una forma elegante de comprobar si faltan paquetes e instalarlos?
r studiodio (26)
Aquí está mi código para ello:
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)
Parece que estoy compartiendo mucho código con coautores en estos días. Muchos de ellos son usuarios novatos / intermedios de R y no se dan cuenta de que tienen que instalar paquetes que aún no tienen.
¿Hay una forma elegante de llamar a installed.packages()
, comparar eso con los que estoy cargando e instalar si faltan?
Aunque la respuesta de Shane es realmente buena, para uno de mis proyectos necesitaba eliminar los mensajes de salida, las advertencias y los paquetes de instalación automágicamente . Finalmente he logrado obtener este 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)
}
Utilizar:
libraries <- c("ReadImages", "ggplot2")
for(library in libraries)
{
if(!UsePackage(library))
{
stop("Error!", library)
}
}
Bastante básico.
pkgs = c("pacman","data.table")
if(length(new.pkgs <- setdiff(pkgs, rownames(installed.packages())))) install.packages(new.pkgs)
Con respecto a su objetivo principal "instalar bibliotecas que ya no tienen" e independientemente de usar "instllaed.packages ()". La siguiente función enmascara la función original de require. Intenta cargar y verificar el paquete con el nombre "x"; si no está instalado, instálelo directamente, incluidas las dependencias; y por último cargarlo normalmente. cambia el nombre de la función de ''require'' a ''library'' para mantener la integridad. La única limitación es que los nombres de los paquetes deben ser citados.
require <- function(x) {
if (!base::require(x, character.only = TRUE)) {
install.packages(x, dep = TRUE) ;
base::require(x, character.only = TRUE)
}
}
Para que pueda cargar e instalar el paquete a la manera antigua de R. require ("ggplot2") require ("Rcpp")
Dason K. y yo tenemos el paquete pacman que puede hacer esto muy bien. La función p_load
en el paquete hace esto. La primera línea es solo para asegurarse de que pacman esté instalado.
if (!require("pacman")) install.packages("pacman")
pacman::p_load(package1, package2, package_n)
En mi caso, quería un liner que pudiera ejecutar desde la línea de comandos (en realidad a través de un Makefile). Aquí hay un ejemplo de instalación de "VGAM" y "feather" si aún no están instalados:
R -e ''for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")''
Desde dentro de R solo sería:
for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")
No hay nada aquí más allá de las soluciones anteriores, excepto que:
- Lo guardo en una sola línea
-
repos
parámetrorepos
(para evitar cualquier ventana emergente que pregunte sobre el espejo que se va a usar) - No me molesto en definir una función para ser usada en otro lugar.
También tenga en cuenta el character.only=TRUE
importante.only character.only=TRUE
(sin él, el require
intentaría cargar el paquete p
).
Esta solución tomará un vector de caracteres de los nombres de paquetes e intentará cargarlos, o los instalará si falla la carga. Se basa en el comportamiento de retorno de require
hacer esto porque ...
require
devoluciones (invisiblemente) un indicador lógico si el paquete requerido está disponible
Por lo tanto, simplemente podemos ver si pudimos cargar el paquete requerido y, si no, instalarlo con dependencias. Así que dado un vector de caracteres de los paquetes que desea cargar ...
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" ) )
Este es el propósito del paquete rbundler : proporcionar una manera de controlar los paquetes que se instalan para un proyecto específico. En este momento, el paquete funciona con la funcionalidad devtools para instalar paquetes en el directorio de su proyecto. La funcionalidad es similar a la del bundler de Ruby.
Si su proyecto es un paquete (recomendado), todo lo que tiene que hacer es cargar rbundler y agrupar los paquetes. La función de bundle
mirará el archivo de DESCRIPTION
su paquete para determinar qué paquetes agrupar.
library(rbundler)
bundle(''.'', repos="http://cran.us.r-project.org")
Ahora los paquetes se instalarán en el directorio .Rbundle.
Si su proyecto no es un paquete, puede falsificarlo creando un archivo de DESCRIPTION
en el directorio raíz de su proyecto con un campo Depende que enumera los paquetes que desea instalar (con información de versión opcional):
Depends: ggplot2 (>= 0.9.2), arm, glmnet
Aquí está el repositorio de github para el proyecto si está interesado en contribuir: rbundler .
He implementado la función para instalar y cargar silenciosamente los paquetes R necesarios. La esperanza podría ayudar. Aquí está el código:
# 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);
La siguiente función simple funciona como un amuleto:
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)
}
(No es mío, encontré esto en la web hace algún tiempo y lo había estado usando desde entonces. No estoy seguro de la fuente original)
Muchas de las respuestas anteriores (y en los duplicados de esta pregunta) se basan en paquetes de installed.packages
cual es incorrecto. De la documentación:
Esto puede ser lento cuando se instalan miles de paquetes, así que no lo use para averiguar si un paquete con nombre está instalado (use system.file o find.package) ni para averiguar si un paquete es utilizable (llame y verifique el devuelva el valor) ni para encontrar detalles de una pequeña cantidad de paquetes (use packageDescription). Necesita leer varios archivos por paquete instalado, que será lento en Windows y en algunos sistemas de archivos montados en la red.
Por lo tanto, un mejor enfoque es intentar cargar el paquete utilizando require
e instalar si falla la carga ( require
devolverá FALSE
si no se encuentra). Prefiero esta implementación:
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)
}
}
que se puede utilizar de esta manera:
using("RCurl","ggplot2","jsonlite","magrittr")
De esta manera, carga todos los paquetes, luego regresa e instala todos los paquetes faltantes (que, si lo desea, es un lugar útil para insertar un mensaje para preguntar si el usuario desea instalar paquetes). En lugar de llamar a install.packages
por separado para cada paquete, pasa todo el vector de paquetes desinstalados solo una vez.
Esta es la misma función pero con un cuadro de diálogo de Windows que pregunta si el usuario desea instalar los paquetes faltantes.
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)
}
}
}
Pensé en aportar el que yo uso:
testin <- function(package){if (!package %in% installed.packages())
install.packages(package)}
testin("packagename")
Por supuesto.
Debe comparar ''paquetes instalados'' con ''paquetes deseados''. Eso es muy CRANberries a lo que hago con CRANberries ya que necesito comparar ''paquetes conocidos almacenados'' con ''paquetes conocidos actualmente'' para determinar paquetes nuevos y / o actualizados.
Entonces haz algo como
AP <- available.packages(contrib.url(repos[i,"url"])) # available t repos[i]
para obtener todos los paquetes conocidos, haga una llamada simular a los paquetes actualmente instalados y compárelos con un conjunto dado de paquetes de destino.
Sí. Si tiene su lista de paquetes, compárela con la salida de installed.packages()[,"Package"]
e instale los paquetes faltantes. Algo como esto:
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)
De otra manera:
Si coloca su código en un paquete y los hace dependientes, entonces se instalarán automáticamente cuando instale su paquete.
Simplemente puede usar la función setdiff
para obtener los paquetes que no están instalados y luego instalarlos. En el ejemplo a continuación, verificamos si los paquetes ggplot2
y Rcpp
están instalados antes de instalarlos.
unavailable <- setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages()))
install.packages(unavailable)
En una línea, lo anterior se puede escribir como:
install.packages(setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages())))
Solo puedes usar el valor de retorno de require
:
if(!require(somepackage)){
install.packages("somepackage")
library(somepackage)
}
Utilizo la library
después de la instalación porque generará una excepción si la instalación no fue exitosa o el paquete no se puede cargar por alguna otra razón. Haces esto más robusto y reutilizable:
dynamic_require <- function(package){
if(eval(parse(text=paste("require(",package,")")))) return True
install.packages(package)
return eval(parse(text=paste("require(",package,")")))
}
La desventaja de este método es que tiene que pasar el nombre del paquete entre comillas, lo que no hace por la require
real.
Usando el enfoque de la función de la familia y el anonimato, usted puede:
lbs <- c("plyr", "psych", "tm")
req <- substitute(require(x, character.only = TRUE))
sapply(lbs, function(x) eval(req) || {install.packages(x); eval(req)})
plyr psych tm
TRUE TRUE TRUE
- Trate de adjuntar todos los paquetes listados.
- Solo falta la instalación (utilizando
||
evaluación perezosa). - Intente cargar de nuevo los que faltaban en el paso 1 y se instaló en el paso 2.
- Imprime un estado de carga de resumen total por cada paquete (
TRUE
/FALSE
).
Use packrat
para que las bibliotecas compartidas sean exactamente iguales y no cambien el entorno de otros.
En cuanto a la elegancia y las mejores prácticas, creo que fundamentalmente lo haces de forma incorrecta. El paquete packrat
fue diseñado para estos problemas. Está desarrollado por RStudio por Hadley Wickham. En lugar de tener que instalar dependencias y posiblemente desordenar el entorno de alguien, el sistema packrat
utiliza su propio directorio e instala todas las dependencias para sus programas en su entorno y no toca el entorno de alguien.
Packrat es un sistema de gestión de dependencias para R.
Las dependencias del paquete R pueden ser frustrantes. ¿Alguna vez ha tenido que usar el método de prueba y error para descubrir qué paquetes de R necesita instalar para que el código de otra persona funcione, y luego se quedó con esos paquetes instalados globalmente para siempre, porque ahora no está seguro si los necesita? ? ¿Alguna vez ha actualizado un paquete para que el código de uno de sus proyectos funcione, solo para encontrar que el paquete actualizado hace que el código de otro proyecto deje de funcionar?
Construimos packrat para resolver estos problemas. Usa packrat para hacer tus proyectos de R más:
- Aislado: la instalación de un paquete nuevo o actualizado para un proyecto no interrumpirá sus otros proyectos, y viceversa. Eso es porque packrat le da a cada proyecto su propia biblioteca de paquetes privada.
- Portátil: transporte fácilmente sus proyectos de una computadora a otra, incluso a través de diferentes plataformas. Packrat facilita la instalación de los paquetes de los que depende su proyecto.
- Reproducible: Packrat registra las versiones exactas del paquete de las que depende, y garantiza que esas versiones exactas sean las que se instalan donde quiera que vaya.
Uso lo siguiente que verificará si el paquete está instalado y si las dependencias están actualizadas, luego carga el paquete.
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, ])
}
Utilizo la siguiente función para instalar el paquete si require("<package>")
sale con el error del paquete no encontrado. Se consultarán los repositorios CRAN y Bioconductor para el paquete faltante.
Adaptado del trabajo original por 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)))
}
}
Ejemplo:
install.packages.auto(qvalue) # from bioconductor
install.packages.auto(rNMF) # from CRAN
PS: update.packages(ask = FALSE)
y biocLite(character(), ask=FALSE)
actualizarán todos los paquetes instalados en el sistema. Esto puede llevar mucho tiempo y considérelo como una actualización completa de R, que puede no estar garantizada todo el tiempo.
prueba esto:
if (!require(MyDesiredLibrary)) {
install.packages("MyDesiredLibrary")
}
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 }
# 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)
if (!require(''ggplot2'')) install.packages(''ggplot2''); library(''ggplot2'')
"ggplot2" es el paquete. Comprueba si el paquete está instalado, si no lo está, lo instala. A continuación, carga el paquete independientemente de la rama que tomó.
library <- function(x){
x = toString(substitute(x))
if(!require(x,character.only=TRUE)){
install.packages(x)
base::library(x,character.only=TRUE)
}}
Esto funciona con nombres de paquetes no citados y es bastante elegante (consulte la respuesta de GeoObserver)
source("https://bioconductor.org/biocLite.R")
if (!require("ggsci")) biocLite("ggsci")