3、包管理工具介绍:remotes、devtools、pak的适用场景与基本用法
做R包开发,装包不是只敲一个 install.packages() 就完事了。尤其是当你遇到依赖冲突、版本锁定、或者要装GitHub上的开发版时,内置函数往往力不从心。
这时候你需要专门的包管理工具。我个人常用三个:remotes、devtools 和 pak。它们各有侧重,但很多人分不清该用谁。我最早也踩过坑——用devtools装一个纯依赖包,结果它把整个编译链都拖下来了,慢得离谱。
三个工具,各自定位不同
咱们先捋一下它们之间的关系。devtools是个大而全的“开发套件”,不光管安装,还管测试、文档、检查。remotes则是它内部的一个轻量模块,后来独立成包,专门负责“从各种来源安装”。pak更年轻,是RStudio团队的新作品,主打并行下载+依赖解析,速度和稳定性都上了一个台阶。
我自己的经验是:
- 如果只是临时装一个GitHub包,用 remotes 就够了,轻巧无负担。
- 如果你在写包、需要做单元测试或生成文档,那 devtools 全家桶更合适。
- 如果你是生产环境、或者要批量安装几十个包,pak 是首选——它不会因为一个包失败就让整个安装停掉。
| 工具 | 主要场景 | 依赖数量 | 并行安装 | 我的推荐 |
|---|---|---|---|---|
| remotes | 从GitHub/GitLab/BitBucket/本地安装 | 极少 | 否 | 快速装一两个包 |
| devtools | 开发全流程(安装+测试+文档+检查) | 多 | 否 | R包开发日常 |
| pak | 高可靠安装、依赖冲突解决、离线安装 | 中等 | 是(5线程) | 生产环境/大项目 |
remotes:轻装上阵,专治“从别处装包”
remotes的核心思路就一个——把你从CRAN之外的来源拉包进来。GitHub、GitLab、BitBucket、本地tar.gz、甚至一个URL都可以。代码很直观:
# 从GitHub安装(默认master分支)
remotes::install_github("tidyverse/dplyr")
# 指定分支或tag
remotes::install_github("rstudio/shiny@v1.7.4")
# 从GitLab
remotes::install_gitlab("user/repo")
# 从本地的压缩包
remotes::install_local("~/Downloads/mypackage_1.0.tar.gz")
我最喜欢它的 install_deps() 函数。当你拿到一个包的源码,只想把它的依赖都安好,不需要编译这个包本身时,这个函数特别爽。举个例子:
# 下载一个包的源码后,只安装它的依赖
remotes::install_deps(".", dependencies = TRUE)
一点经验:如果你从GitHub装包老是失败,先检查一下是不是网络问题。在国内建议设置代理:Sys.setenv(GITHUB_TOKEN = "你的token") 可以提升速率。
devtools:瑞士军刀,但请按需使用
devtools是Hadley Wickham的杰作,几乎每个R包开发者都绕不开它。它把remotes、testthat、roxygen2这些工具打包在一起。安装命令跟remotes很像,但因为依赖多,第一次安装要等很久。
# devtools安装GitHub包
devtools::install_github("hadley/ggplot2")
# 安装本地包(会自动构建)
devtools::install_local("~/my_package")
# 安装依赖(区别于remotes,devtools只装depends)
devtools::install_deps(".")
你可能会问:既然devtools包含了remotes,那我是不是只用devtools就行了?
我个人建议:做普通安装时,别轻易用devtools。原因是它会依赖很多开发工具(如roxygen2、testthat、pkgbuild等),如果你只是装包用,这些完全多余。我在一个服务器上因为装devtools而搞出了gcc版本冲突,折腾了半小时。
避坑指南:千万不要用devtools::install_github()来装devtools自己——这会产生循环依赖。先装remotes,再用remotes装devtools是标准做法。
pak:下一代安装利器,快且稳
pak是RStudio在2021年推出的新工具,用C++重写了核心依赖解析引擎。它的特点:
- 并行下载:默认5个线程同时拉包,速度翻倍。
- 智能缓存:第二次装同一个包几乎不花时间。
- 冲突处理:当多个包对同一依赖有版本需求时,pak会自动选一个合理版本,而不是报错。
# 安装pak本体(需从GitHub或源代码装)
install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/")
# 基本用法:安装一个包
pak::pkg_install("dplyr")
# 批量安装多个
pak::pkg_install(c("tidyverse", "shiny", "rmarkdown"))
# 从GitHub安装(语法类似remotes)
pak::pkg_install("tidyverse/ggplot2")
# 查看安装计划(不实际安装,只预览依赖树)
pak::pkg_deps_tree("ggplot2")
我去年帮一个团队部署R环境,150多个包用install.packages装了快两小时,还中途断了两次。换成pak后,同样是那些包,35分钟搞定,而且中途网络闪断时它自动重试了。
SVG:三工具选择决策图
下面这张图帮你快速判断当前场景该用谁。记住:先看“是不是开发”,再问“是不是批量”。
对比表格:命令对应关系
为了方便你记忆,我把三个工具的常用命令放在一起对比。你会发现,核心功能差异很小,主要区别在附加能力。
| 操作 | remotes | devtools | pak |
|---|---|---|---|
| 装GitHub包 | install_github() |
install_github() |
pkg_install("user/repo") |
| 装本地包 | install_local() |
install_local() |
pkg_install("path") |
| 装依赖 | install_deps() |
install_deps() |
pak::pkg_deps() |
| 卸载包 | 无 | 无 | pkg_remove() |
| 查看版本冲突 | 无 | 无 | pkg_deps_tree() |
避坑清单:我踩过的三个雷
最后,分享几个我用这些工具时遇到的典型问题,希望你能直接跳过。
- 忘了重启R会话:用remotes装完包后,如果发现新包的函数找不到,八成是没重启。最好在装完后执行
.rs.restartR()(RStudio)或重新打开R。 - 依赖版本冲突时硬装:我遇到过装一个包需要dplyr 1.0,另一个需要0.8。两个都用
install.packages直接报错。用pak的话,它会自动降级/升级其中一个依赖,并且告诉你原因。 - 从GitHub装私有仓库没认证:如果你在公司的私有GitHub上,记得先用
Sys.setenv(GITHUB_PAT = "你的token")设置环境变量。remotes和devtools都能识别这个变量,但pak需要用pak::pkg_install(credentials = gitcreds::gitcreds_get())。
一句话总结:日常装包首选pak,快、稳、智能;做包开发用devtools;只装一两个远程包时,用remotes最轻便。