我有一个在学习 R 时编写的包,它的依赖项列表很长。我正在尝试将其缩小,分两种情况:
- 我改用了其他方法,并且根本没有使用
建议
中列出的软件包。 - 我的整个包中只有一个函数依赖于给定的依赖项,我想切换到 loaded only when needed. 的方法。
有没有一种自动化的方法来追踪这两种情况?我可以想到两种粗略的方法(下载所有依赖包中的函数列表并通过我的包代码自动对它们进行文本搜索,或者加载包函数而不加载所需的包并执行直到出现错误),但是都没有看起来特别优雅或万无一失......
最佳答案
检查所有函数中的依赖性的一种方法是使用字节编译器,因为它将检查全局工作区中可用的函数,并在找不到所述函数时发出通知。
因此,如果您作为示例在任何函数中使用 Zoo 包中的 na.locf 函数,然后对函数进行字节编译,您将收到如下消息:
Note: no visible global function definition for 'na.locf'
要正确寻址它以进行字节编译,您必须将其编写为zoo::na.locf
因此,有一种快速测试库/包中所有 R 函数的方法,您可以执行类似的操作(假设您没有使用命名空间编写对其他函数的调用):
假设带有函数的 R 文件位于 C:\SomeLibrary\或其子文件夹中,然后将源文件定义为 C:\SomeLibrary.r 或类似文件,其中包含:
if (!(as.numeric(R.Version()$major) >=2 && as.numeric(R.Version()$minor) >= 14.0)) {
stop("SomeLibrary needs version 2.14.0 or greater.")
}
if ("SomeLibrary" %in% search()) {
detach("SomeLibrary")
}
currentlyInWorkspace <- ls()
SomeLibrary <- new.env(parent=globalenv())
require("compiler",quietly=TRUE)
pathToLoad <- "C:/SomeLibraryFiles"
filesToSource <- file.path(pathToLoad,dir(pathToLoad,recursive=TRUE)[grepl(".*[\\.R|\\.r].*",dir(pathToLoad,recursive=TRUE))])
for (filename in filesToSource) {
tryCatch({
suppressWarnings(sys.source(filename, envir=SomeLibrary))
},error=function(ex) {
cat("Failed to source: ",filename,"\n")
print(ex)
})
}
for(SomeLibraryFunction in ls(SomeLibrary)) {
if (class(get(SomeLibraryFunction,envir=SomeLibrary))=="function") {
outText <- capture.output(with(SomeLibrary,assign(SomeLibraryFunction,cmpfun(get(SomeLibraryFunction)))))
if(length(outText)>0){
cat("The function ",SomeLibraryFunction," produced the following compile note(s):\n")
cat(outText,sep="\n")
cat("\n")
}
}
}
attach(SomeLibrary)
rm(list=ls()[!ls() %in% currentlyInWorkspace])
invisible(gc(verbose=FALSE,reset=TRUE))
然后在 C:\SomeLibrary.r 中启动没有预加载软件包和源代码的 R
然后,您应该从 cmpfun 获取注释,了解对不属于基础包且未定义完全限定命名空间的包中函数的任何调用。
关于r - 搜索所有现有函数以查找包依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9815378/