脱机安装软件包列表:按顺序获取依赖项 [英] Offline installation of a list of packages: getting dependencies in order

查看:106
本文介绍了脱机安装软件包列表:按顺序获取依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆软件包的源文件及其依赖项,我想将它们安装在无法访问互联网的计算机上。我想使用USB记忆棒在所有其他计算机上安装所有这些软件,但是某些软件包的安装失败,因为相关性没有在软件包之前安装。在需要它们的软件包之前,如何才能按顺序安装依赖项?

I've got the source files for a bunch of packages and their dependencies that I want to install on computers that have no internet access. I want to install all of these on other computers using as USB stick, but the install fails for some packages because the dependencies are not installing before the packages. How can I get the dependencies to be installed in order, before the packages that needs them?

这是我当前的方法,用于获取软件包,它们的依赖关系并将其放入正确的顺序:

Here's my current method to obtain the packages, their dependencies, and get them in the correct order:

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

现在假设我在另一台装有R和RStudio(以及Rtools或Xcode)的全新安装并且没有互联网连接的计算机上,我插入了USB记忆棒,打开RProj文件来设置工作目录,然后运行以下脚本:

Now assume I'm on another computer with a fresh install of R and RStudio (and Rtools or Xcode) and no internet connection, I plug in the USB stick, open the RProj file to set the working directory, and run this 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" )

这可以很好地工作,但是仍然有些软件包无法安装:

This works reasonably well, but still some packages fail to install:

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’

似乎编织器必须在rmarkdown之前,tshapeyr和ggplot2之前的reshape2之前出现,等等。

Seems that knitr must come before rmarkdown, reshape2 before tidyr and ggplot2, etc. etc.

必须有一个更简单,更完整的解决方案来解决按照非常特定的顺序获取源文件列表所需要的问题,即按照正确的顺序放置所有依赖项。最简单的方法是什么(不使用任何贡献的软件包)?

There must be a simpler and more complete solution to the problem of getting the list of source files in the very specific order needed the put all the dependencies in the right order. What's the simplest way to do that (without using any contributed packages)?

这是我目前正在使用的系统,我使用的是软件包的源版本尝试使用离线计算机(OSX / Linux / Windows)进行准备:

This is the system I am currently working on, I'm using the source versions of packages in an attempt to prepare for anything with the offline computers (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

编辑,在安德里(Andrie)的有用评论之后,我对miniCRAN有所了解,小插图遗漏的一点是如何从本地存储库实际安装软件包。这是我尝试过的:

EDIT following Andrie's helpful comment, I've had a go with miniCRAN, the bit that's missing from the vignette is how to actually install the packages from the local repo. This is what I've tried:

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

结果是:

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)

我在这里错过了什么?

编辑是,我缺少正确使用 file:/// ,应该像这样:

EDIT Yes, I was missing proper use of file:///, which should be like this:

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

这让我感到很困惑,现在基本上一切都按预期进行了。非常感谢。现在,我只需要查看以下内容:严重错误:curl / curl.h:没有这样的文件或目录,这将阻止RCurl和httr的安装。

That's moved me along heaps, it all basically works as expected now. Thanks very much. Now I just have this to look in to: fatal error: curl/curl.h: No such file or directory, which is stopping RCurl and httr from installing.

推荐答案

软件包 miniCRAN 可以帮助解决此问题。您将 miniCRAN 告诉您要安装的软件包列表,然后找出依赖关系,下载这些软件包,并在本地计算机上创建一个行为类似于CRAN的存储库,即它尊重 install.packages()等。

The package miniCRAN can help with this. You tell miniCRAN the list of packages you would ever want to install, it then figures out the dependencies, downloads those packages and creates a repository on your local machine that behaves like CRAN, i.e. it respects install.packages() etc.

更多信息:

阅读渐晕

我们正在积极开发 miniCRAN 。跟踪进度并在 github miniCRAN存储库中找到最新的开发版本

We are actively developing miniCRAN. Track progress and find the latest development version at github miniCRAN repository

请参阅项目Wiki ,以获取演示文稿,博客文章等的链接

See the project wiki for links to presentations, blog posts and more

要从本地 miniCRAN 存储库安装选项。

To install from the local miniCRAN repository, you have two options.


  1. 首先,您可以使用URI约定 file:/// 。例如

install.packages("ggplot2", repos="file:///path/to/file/")


  • 或者,您可以将目标配置为HTTP服务器,并通过URL使存储库可用。在这种情况下,您的本地存储库的外观和感觉完全类似于CRAN镜像,只是它只包含所需的软件包。

  • Alternatively, you can configure the destination as an HTTP server and make your repository available via a URL. In this case, your local repository will look and feel exactly like a CRAN mirror, other than it only contains your desired packages.

    这篇关于脱机安装软件包列表:按顺序获取依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆