2015-03-05 14 views
11

Ho i file di origine per un mucchio di pacchetti e le loro dipendenze che voglio installare su computer che non hanno accesso a Internet. Voglio installare tutti questi su altri computer usando come chiavetta USB, ma l'installazione non riesce per alcuni pacchetti perché le dipendenze non vengono installate prima dei pacchetti. Come posso ottenere l'installazione delle dipendenze in ordine, prima dei pacchetti che ne hanno bisogno?Installazione offline di un elenco di pacchetti: ottenere le dipendenze nell'ordine

Ecco il mio attuale metodo per ottenere i pacchetti, le loro dipendenze, e farli nell'ordine corretto:

# find the dependencies for the packages I want 
# from http://stackoverflow.com/a/15650828/1036500 
getPackages <- function(packs){ 
    packages <- unlist(
    tools::package_dependencies(packs, available.packages(), 
           which=c("Depends", "Imports"), recursive=TRUE) 
) 
    packages <- union(packages, packs) 
    packages 
} 

# packages I want 
my_packages <- c('stringr', 'devtools', 'ggplot2', 'dplyr', 'tidyr', 'rmarkdown', 'knitr', 'reshape2', 'gdata') 

# get names of dependencies and try to get them in the right order, this seems ridiculous... 
my_packages_and_dependencies <- getPackages(my_packages) 
dependencies_only <- setdiff(my_packages_and_dependencies, my_packages) 
deps_of_deps <- getPackages(dependencies_only) 
deps_of_deps_of_deps <- getPackages(deps_of_deps) 
my_packages_and_dependencies <- unique(c(deps_of_deps_of_deps, deps_of_deps, dependencies_only, my_packages)) 

# where to keep the source? 
local_CRAN <- paste0(getwd(), "/local_CRAN") 

# get them from CRAN, source files 
download.packages(pkgs = my_packages_and_dependencies, destdir = local_CRAN, type = "source") 
# note that 'tools', 'methods', 'utils, 'stats', etc. art not on CRAN, but are part of base 

# from http://stackoverflow.com/a/10841614/1036500 
library(tools) 
write_PACKAGES(local_CRAN) 

Ora assumere sono su un altro computer con una nuova installazione di R e RStudio (e Rtools o Xcode) e senza connessione a internet, inserisco la chiavetta USB, aprire il file RProj per impostare la directory di lavoro, ed eseguire questo script:

############################################################# 

## Install from source (Windows/OSX/Linux) 

# What do I want to install? 
my_packages_and_dependencies <- c("methods", "tools", "bitops", "stats", "colorspace", "graphics", 
            "tcltk", "Rcpp", "digest", "jsonlite", "mime", "RCurl", "R6", 
            "stringr", "brew", "grid", "RColorBrewer", "dichromat", "munsell", 
            "plyr", "labeling", "grDevices", "utils", "httr", "memoise", 
            "whisker", "evaluate", "rstudioapi", "roxygen2", "gtable", "scales", 
            "proto", "MASS", "assertthat", "magrittr", "lazyeval", "DBI", 
            "stringi", "yaml", "htmltools", "caTools", "formatR", "highr", 
            "markdown", "gtools", "devtools", "ggplot2", "dplyr", "tidyr", 
            "rmarkdown", "knitr", "reshape2", "gdata") 

# where are the source files? 
local_CRAN <- paste0(getwd(), "/local_CRAN") 

# scan all packages and get files names of wanted source pckgs 
# I've got other things in this dir also 
wanted_package_source_filenames <- list.files(local_CRAN, pattern = "tar.gz", full.names = TRUE) 

# put them in order to make sure deps go first, room for improvement here... 
trims <- c(local_CRAN, "/", "tar.gz") 
x1 <- gsub(paste(trims, collapse = "|"), "", wanted_package_source_filenames) 
x2 <- sapply(strsplit(x1, "_"), "[[", 1) 
idx <- match(my_packages_and_dependencies, x2) 
wanted_package_source_filenames <- na.omit(wanted_package_source_filenames[idx]) 

install.packages(wanted_package_source_filenames, 
       repos = NULL, 
       dependencies = TRUE, 
       contrib.url = local_CRAN, # I thought this would take care of getting dependencies automatically... 
       type = "source") 

questo funziona abbastanza bene, ma ancora alcuni pacchetti non riescono a installare:

sapply(my_packages_and_dependencies, require, character.only = TRUE) 

methods  tools  bitops  stats 
     TRUE   TRUE   TRUE   TRUE 
    colorspace  graphics  tcltk   Rcpp 
     TRUE   TRUE   TRUE   TRUE 
     digest  jsonlite   mime  RCurl 
     TRUE   TRUE   TRUE  FALSE 
      R6  stringr   brew   grid 
     TRUE   TRUE   TRUE   TRUE 
RColorBrewer dichromat  munsell   plyr 
     TRUE   TRUE   TRUE   TRUE 
    labeling grDevices  utils   httr 
     TRUE   TRUE   TRUE  FALSE 
    memoise  whisker  evaluate rstudioapi 
     TRUE   TRUE   TRUE   TRUE 
    roxygen2  gtable  scales  proto 
     TRUE   TRUE   TRUE   TRUE 
     MASS assertthat  magrittr  lazyeval 
     TRUE   TRUE   TRUE   TRUE 
     DBI  stringi   yaml htmltools 
     TRUE   TRUE   TRUE   TRUE 
    caTools  formatR  highr  markdown 
     TRUE   TRUE   TRUE   TRUE 
     gtools  devtools  ggplot2  dplyr 
     TRUE  FALSE  FALSE   TRUE 
     tidyr rmarkdown  knitr  reshape2 
     FALSE  FALSE   TRUE   TRUE 
     gdata 
     TRUE 
Warning messages: 
1: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, : 
    there is no package called ‘RCurl’ 
2: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, : 
    there is no package called ‘httr’ 
3: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, : 
    there is no package called ‘devtools’ 
4: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, : 
    there is no package called ‘ggplot2’ 
5: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, : 
    there is no package called ‘tidyr’ 
6: In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, : 
    there is no package called ‘rmarkdown’ 

sembra che knitr deve venire prima rmarkdown, reshape2 prima tidyr e ggplot2, ecc ecc

Ci deve essere una soluzione più semplice e più completa al problema di ottenere l'elenco dei file di origine in pieno ordine specifico necessario per mettere tutte le dipendenze nel giusto ordine. Qual è il modo più semplice per farlo (senza usare pacchetti contribuiti)?

Questo è il sistema Attualmente sto lavorando, sto utilizzando le versioni di origine dei pacchetti nel tentativo di preparare qualsiasi cosa con i computer fuori linea (OSX/Linux/Windows):

> sessionInfo() 
R version 3.1.2 (2014-10-31) 
Platform: x86_64-w64-mingw32/x64 (64-bit) 

locale: 
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252 
[3] LC_MONETARY=English_United States.1252 
[4] LC_NUMERIC=C       
[5] LC_TIME=English_United States.1252  

attached base packages: 
[1] tcltk  grid  tools  stats  graphics 
[6] grDevices utils  datasets methods base  

other attached packages: 
[1] gdata_2.13.3  reshape2_1.4.1  
[3] knitr_1.9   dplyr_0.4.1  
[5] gtools_3.4.1  markdown_0.7.4  
[7] highr_0.4   formatR_1.0  
[9] caTools_1.17.1  htmltools_0.2.6 
[11] yaml_2.1.13  stringi_0.4-1  
[13] DBI_0.3.1   lazyeval_0.1.10 
[15] magrittr_1.5  assertthat_0.1  
[17] proto_0.3-10  scales_0.2.4  
[19] gtable_0.1.2  roxygen2_4.1.0  
[21] rstudioapi_0.2  evaluate_0.5.5  
[23] whisker_0.3-2  memoise_0.2.1  
[25] labeling_0.3  plyr_1.8.1   
[27] munsell_0.4.2  dichromat_2.0-0 
[29] RColorBrewer_1.1-2 brew_1.0-6   
[31] stringr_0.6.2  R6_2.0.1   
[33] mime_0.2   jsonlite_0.9.14 
[35] digest_0.6.8  Rcpp_0.11.4  
[37] colorspace_1.2-5 bitops_1.0-6  
[39] MASS_7.3-35  

loaded via a namespace (and not attached): 
[1] parallel_3.1.2 

EDIT seguendo il commento utile di Andrie, ho avuto un tentativo con miniCRAN, il bit che manca dalla vignetta è come installare effettivamente i pacchetti dal repository locale. Questo è quello che ho provato:

library("miniCRAN") 

# Specify list of packages to download 
pkgs <- c('stringr', 'devtools', 'ggplot2', 'dplyr', 'tidyr', 'rmarkdown', 'knitr', 'reshape2', 'gdata') 

# Make list of package URLs 
revolution <- c(CRAN="http://cran.revolutionanalytics.com") 
pkgList <- pkgDep(pkgs, repos=revolution, type="source") 
pkgList 

# Set location to store source files 
local_CRAN <- paste0(getwd(), "/local_CRAN") 

# Make repo for source 
makeRepo(pkgList, path = local_CRAN, repos = revolution, type = "source") 

# install... 
install.packages(pkgs, 
       repos = local_CRAN, # do I really need "file:///"? 
       dependencies = TRUE, 
       contrib.url = local_CRAN, 
       type = "source") 

E il risultato è:

Installing packages into ‘C:/emacs/R/win-library/3.1’ 
(as ‘lib’ is unspecified) 
Warning in install.packages : 
    unable to access index for repository C:/Users/.../local_CRAN/src/contrib 
Warning in install.packages : 
    packages ‘stringr’, ‘devtools’, ‘ggplot2’, ‘dplyr’, ‘tidyr’, ‘rmarkdown’, ‘knitr’, ‘reshape2’, ‘gdata’ are not available (for R version 3.1.2) 

Che cosa mi manca qui?

EDIT Sì, mi mancava l'uso corretto di file:///, che dovrebbe essere simile a questo:

install.packages(pkgs, 
       repos = paste0("file:///", local_CRAN), 
       type = "source") 

Questo mi ha spostato lungo cumuli, tutto funziona praticamente come previsto ora. Grazie mille. Ora devo solo controllare: fatal error: curl/curl.h: No such file or directory, che sta impedendo l'installazione di RCurl e httr.

+3

Il mio pacchetto 'miniCRAN' può essere d'aiuto. Dì a 'miniCRAN' l'elenco dei pacchetti che vorresti installare, poi scarica quei pacchetti e crea un repository sul tuo computer locale che si comporta come CRAN, cioè rispetta' install.packages() 'ecc. Vedi http://cran.r-project.org/web/packages/miniCRAN/index.html – Andrie

+0

@Andrie Sembra una cosa ragionevole da postare in una risposta – Dason

+1

È possibile eseguire il loop sui file DESCRIPTION, contando il numero di dipendenze? Quindi installare prima tutti i pacchetti senza dipendenze, quelli con una sola dipendenza (ordinando in qualche modo se i loro nomi fossero nell'elenco di altri pacchetti di dipendenze singoli) e così via "down the line"? –

risposta

12

Il pacchetto miniCRAN può essere d'aiuto. Dì allo miniCRAN l'elenco di pacchetti che vorresti installare, poi calcola le dipendenze, scarica quei pacchetti e crea un repository sul tuo computer locale che si comporta come CRAN, cioè rispetta lo install.packages() ecc.

Maggiori informazioni:

installare dal repository locale miniCRAN, si hanno due opzioni.

  1. In primo luogo, è possibile utilizzare la convenzione URI file:///. per esempio.

    install.packages("ggplot2", repos="file:///path/to/file/") 
    
  2. In alternativa, è possibile configurare la destinazione come un server HTTP e rendere il repository disponibile tramite un URL. In questo caso, il tuo repository locale apparirà esattamente come un mirror CRAN, a parte che contiene solo i pacchetti desiderati.

+0

Grazie mille, sembra molto rilevante. Ho avuto un tentativo con esso e mi sono un po 'bloccato, ti dispiacerebbe controllare la mia modifica del mio Q? – Ben

+0

@ Ben ho modificato la mia risposta – Andrie

+0

Grazie ancora, questo è praticamente risolto il problema. Solo un puzzle di RCurl da risolvere adesso, ma questa è un'altra domanda ... – Ben