>实际问题
是否可以在需要/加载软件包后覆盖对软件包(重新)安装的阻止?
我知道,一旦使用软件包,阻止"真正">重新安装到加载软件包的同一库中是完全有意义的。但我的用例有点不同
背景
我喜欢拥有一个"沙盒库"来测试自己的包的想法。除了要测试的包之外,这些沙盒库还包含干净的基本 R 安装的所有基本包,以及我的整个包构建和测试框架工作所需的一些 contrib 包(例如digest
、stringr
等)。但是,我的框架从标准库加载后一个包,然后需要将它们安装到沙盒库 - 沙盒库被阻止。因此,我的问题是否可以覆盖它,因为我并没有真正做人们在实施块时的想法。
插图
指定两个库的路径
lib <- file.path(R.home(), "library")
lib.sandbox <- file.path(tempdir(), "library")
创建沙盒库
dir.create(lib.sandbox, showWarnings=FALSE)
将软件包安装到标准库并加载它
install.packages("digest", lib=lib)
require("digest", lib.loc=lib)
然后还要将其安装到沙盒库中
> install.packages("digest", lib=lib.sandbox)
Warning: package 'digest' is in use and will not be installed
我的框架在加载某些也应该安装到沙盒库的包后会找出某些东西,所以我不能在初始加载步骤之前放置"安装到沙盒库"步骤。
这是您在答案中建议的一般版本。这将在安装之前卸载包,然后从同一位置重新加载包。
install.packages.sandbox <- function(pkgs, lib, repos=getOption("repos"), ...) {
if (is.null(repos))
stop("Can't install from source. Need package name.")
pkg.pos <- grep(pkgs, search())
pkg.path <- searchpaths()[grep(pkgs, searchpaths())]
in.use <- length(pkg.pos) > 0
# detach
if (in.use) do.call(detach,
list(pkg.pos),
envir=.GlobalEnv)
# install
utils::install.packages(pkgs, lib, repos, ...)
# re-attach from original library location
if (in.use) library(pkgs,
character.only=TRUE,
lib.loc=.libPaths()[sapply(.libPaths(), grepl, pkg.path)])
}
不是我在概念上所追求的,而是一个务实的解决方法:在安装之前立即分离软件包
指定两个库的路径
lib <- file.path(R.home(), "library")
lib.sandbox <- file.path(tempdir(), "library")
创建沙盒库
dir.create(lib.sandbox, showWarnings=FALSE)
将软件包安装到标准库并加载它
install.packages("digest", lib=lib)
require("digest", lib.loc=lib)
分离包
detach(package:digest)
然后还要将其安装到沙盒库中
> install.packages("digest", lib=lib.sandbox)
trying URL 'http://cran.at.r-project.org/bin/windows/contrib/2.15/digest_0.5.2.zip'
Content type 'application/zip' length 79053 bytes (77 Kb)
opened URL
downloaded 77 Kb
package 'digest' successfully unpacked and MD5 sums checked
The downloaded binary packages are in
C:Userswwa418AppDataLocalTempRtmp6XSVYqdownloaded_packages
除了已经提到的搜索路径更改方法之外,可能值得注意的是,此警告和行为来自(至少从 R 3.6.2 开始)来自utils:::.install.winbinary
,其中对附加的包进行了检查。
因此,我们可以做的替代方法来规避此问题,而不是使用二进制安装方法,而是从源代码安装软件包:
library(digest)
utils::install.packages("digest", lib = tempdir(), type = "source")
当然,如果软件包需要编译 C/C++/Fortran 代码,这会带来一些潜在的警告,如 Windowshelp("install.packages")
编写的那样:
使用类型为 ="source" 的包始终有效,前提是包 不包含需要编译的 C/C++/Fortran 代码。否则,您 需要按照 "R for Windows FAQ",您必须具有 PATH 环境变量 根据 Rtools 的要求进行设置。
。