Pregunta

Me parece estar compartiendo un montón de código con coautores estos días. Muchos de ellos son novatos / R usuarios intermedios y no se dan cuenta de que tienen que instalar los paquetes es que aún no lo han hecho.

¿Hay una manera elegante de installed.packages() llamada, compararlo con los que yo soy de carga e instalar si falta?

¿Fue útil?

Solución

Sí. Si usted tiene su lista de paquetes, compararlo con la salida de installed.packages()[,"Package"] e instalar los paquetes que faltan. 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 otro modo:

Si usted pone su código en un paquete y hacer que las dependencias, entonces automáticamente se instalan al instalar el paquete.

Otros consejos

Dason K. y yo tenemos la paquete pacman que puede hacer esto muy bien. El p_load función en el paquete hace esto. La primera línea es sólo para asegurarse de que está instalado pacman.

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

Usted sólo puede usar el valor de retorno de require:

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

Yo uso library después de la instalación, ya que se producirá una excepción si la instalación no se ha realizado correctamente o el paquete no se puede cargar por alguna otra razón. Usted hace 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 usted tiene que pasar el nombre del paquete entre comillas, que no lo hace para el require real.

Esta solución tendrá un vector de caracteres de nombres de paquetes e intentará cargarlos, o instalarlos si la carga falla. Se basa en el comportamiento de retorno de require hacer esto porque ...

  

require retornos (invisible) una lógica que indica si el paquete requerido está disponible

Por lo tanto podemos simplemente ver si hemos sido capaces de 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" ) )
if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')

"ggplot2" es el paquete. Se comprueba si está instalado el paquete, si no es que lo instala. A continuación, carga el paquete, independientemente de la rama que hiciera falta.

A pesar de que la respuesta de Shane es realmente bueno, para uno de mi proyecto que necesitaba para eliminar los mensajes ouput, advertencias e instalar los paquetes automagicamente . Por fin he conseguido que 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)
}

Uso:

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

Muchas de las respuestas anteriores (y sobre los duplicados de esta pregunta) se basan en installed.packages que es de mala educación. A partir de la documentación:

  

Esto puede ser lento cuando se instalan miles de paquetes, así que no use esto para descubrir si se ha instalado un paquete llamado (uso system.file o find.package), ni de saber si un paquete es utilizable (llamada requiere y comprobar el valor de retorno), ni para encontrar detalles de un pequeño número de paquetes (uso packageDescription). Se necesita leer varios archivos por paquete instalado, lo que será lento en Windows y en algunos sistemas de archivos montado en red.

Por lo tanto, un mejor enfoque es tratar de cargar el paquete utilizando require e instalar y si falla la carga (require volverá FALSE si no se encuentra). Yo prefiero esta aplicació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 puede ser utilizado como esto:

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

De esta manera se carga todos los paquetes, y luego regresa y se instala todos los paquetes que faltan (que si se quiere, es un lugar práctico para insertar un mensaje para preguntar si el usuario desea instalar paquetes). En lugar de llamar install.packages por separado para cada paquete que pasa todo el vector de paquetes no instalados sólo una vez.

Aquí está la misma función pero con una ventana de diálogo que pregunta al usuario si desea instalar los paquetes que faltan

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)

Este es el propósito de la rbundler paquete : proporcionar una manera de controlar los paquetes que están instalados 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 de bundler .

Rubí

Si su proyecto es un paquete (recomendado) entonces todo lo que tiene que hacer es rbundler carga y el paquete de los paquetes. La función bundle estudiará el archivo DESCRIPTION de su paquete para determinar qué paquetes de paquete.

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, entonces se puede fingir mediante la creación de un archivo DESCRIPTION en el directorio raíz de su proyecto con un campo depende que lista los paquetes que desea instalar (con información de la versión opcional):

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

Aquí está el repositorio GitHub para el proyecto si está interesado en contribuir:. rbundler

Claro.

Es necesario comparar los paquetes instalados '' con '' paquetes deseados. Eso es muy cercano a lo que hago con arándanos ya que necesito para comparar 'paquetes almacenados conocidos' con 'actualmente conocidos paquetes para determinar nuevas y / o actualizadas paquetes.

Así que hacer algo como

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

para obtener todos los paquetes conocidos, llamada similares en los paquetes instalados y compararlo con un determinado conjunto de paquetes de destino.

La siguiente función funciona como un encanto:

  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 la mía, ha encontrado en la web de algunas idas tiempo y habían estado utilizando desde entonces. No está seguro de la fuente original)

Utilice la función siguiente para instalar el paquete si las salidas require("<package>") con el paquete no se encuentra el error. Se consulta tanto -. CRAN y Bioconductor repositorios de paquetes que faltan

Adaptado de la obra original por Joshua Wiley, http: //r.789695.n4 .nabble.com / Install-paquete-de forma automática, si-no-hay-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á todos los paquetes instalados en el sistema. Esto puede llevar mucho tiempo y considerarlo como una actualización completa de I que no puede ser justificado todo el tiempo!

Usted simplemente puede utilizar la función setdiff para obtener los paquetes que no están instalados y luego instalarlos. En el ejemplo siguiente, se comprueba si el ggplot2 y Rcpp se instalan los paquetes 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())))

Uso packrat de manera que las bibliotecas compartidas son exactamente lo mismo y no cambiar el entorno del otro.

En cuanto a la elegancia y las mejores prácticas creo que tu fundamentalmente ir sobre él por el camino equivocado. packrat el paquete fue diseñado para estas cuestiones. Es desarrollado por rstudio por Hadley Wickham. En lugar de que se tengan que instalar las dependencias y posiblemente estropear packrat medio ambiente sistema de alguien utiliza su propio directorio y ensambla todas las dependencias para sus programas en su y no toca entorno de alguien.

  

de Packrat es un sistema de gestión de la dependencia de R.

     

R dependencias del paquete puede ser frustrante. ¿Alguna vez ha tenido que usar ensayo y error para averiguar qué paquetes R es necesario instalar para hacer algún otro código de trabajo y luego se quedan con esos paquetes a nivel mundial instalados para siempre, porque ahora no está seguro de si los necesita ? ¿Alguna vez ha actualizado un paquete para obtener el código en uno de sus proyectos para trabajar, sólo para encontrar que el paquete actualizado hace el código en otro dejan de funcionar proyecto?

     

packrat construido para resolver estos problemas. Uso packrat para hacer sus proyectos de I más:

     
      
  • Aislado: Instalación de un paquete nuevo o actualizado para un proyecto no rompa sus otros proyectos, y viceversa. Esto se debe a packrat da a cada proyecto de su propia biblioteca privada del paquete.
  •   
  • Portátil: Fácil de transportar sus proyectos desde un ordenador a otro, incluso a través de diferentes plataformas. Packrat hace que sea fácil de instalar los paquetes de su proyecto depende.
  •   
  • reproducible:. De Packrat registra las versiones de los paquetes exactos de los que depende, y se asegura de esas versiones exactas son las que se instalan donde quiera que vaya
  •   

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

Me han puesto en marcha la función de instalar y de carga requerida R paquetes en silencio. La esperanza puede 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);

En cuanto a sus principales objetivos "para instalar las bibliotecas que no tiene ya." Y sin tener en cuenta el uso de "instllaed.packages ()". La siguiente función enmascarar la función original de requerir. Se trata de cargar y comprobar el paquete llamado "X", si no está instalado, instalarlo directamente incluyendo dependencias; y por último cargar Normaly. cambiar el nombre del nombre de la función de 'requieren' a 'biblioteca' para mantener la integridad. La única limitación es nombres de 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)
  } 
}

Así que usted puede cargar y paquete instalado a la antigua usanza de R.     requerir ( "ggplot2")     require ( "RCPP")

uno bastante básico.

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

pensé que iba a contribuir al uso de un I:

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

Uso de la familia lapply y enfoque de la función anónima es posible que:

  1. Trate de adjuntar todos los paquetes de la lista.
  2. Instalar sólo faltan (usando || evaluación perezosa).
  3. Intento de unir de nuevo los que faltaban en el paso 1 y instalado en el paso 2.
  4. Imprimir cada paquete estado de carga final (TRUE / FALSE).

    req <- substitute(require(x, character.only = TRUE))
    lbs <- c("plyr", "psych", "tm")
    sapply(lbs, function(x) eval(req) || {install.packages(x); eval(req)})
    
    plyr psych    tm 
    TRUE  TRUE  TRUE 
    

La versión venida de rstudio (1.2), ya está disponible como una vista previa, incluirá una característica para detectar paquetes faltantes en library() y require() llamadas, y solicitan al usuario la instalarlos:

  

detectar la falta de paquetes de I

     

Muchos scripts R abren con llamadas a library() y require() para cargar los paquetes que necesitan con el fin de ejecutar. Si abre un script que R paquetes de referencias que no han instalado, rstudio ofrecerá ahora a instalar todos los paquetes necesarios en un solo clic. No más tipificación install.packages() varias veces hasta que los errores se vaya!
   https: //blog.rstudio .com / 2018/11/19 / rstudio-1-2-preview-la-little-cosas /

Esto parece responder a la inquietud original de OP particularmente bien:

  

Muchos de ellos son novatos / R usuarios intermedios y no se dan cuenta de que tienen que instalar los paquetes es que aún no lo han hecho.

Yo uso el siguiente que comprobará si se ha instalado el paquete y si se actualizan las dependencias, a continuación, 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, ])
}

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)
 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)
}}

Esto funciona con nombres de paquetes no cotizadas y es bastante elegante (cf. respuesta de GeoObserver)

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

En mi caso, yo quería un chiste que podría ejecutar desde la línea de comandos (en realidad a través de un Makefile). Este es un ejemplo de instalar "MAVG" y "pluma" si no están ya 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 el interior de R que sólo sería:

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

Aquí no hay nada más allá de las soluciones anteriores, excepto que:

  • La guardo a una sola línea
  • I codificar el repos parámetro (para evitar cualquier popups preguntando por el espejo de usar)
  • I no se molestan en definir una función para ser utilizado en otra parte

También tenga en cuenta el importante character.only=TRUE (sin ella, la require tratarían de cargar el paquete de p).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top