首先,感谢 @mathematical.coffee 让我走上了使用 Mark Bravington 的道路mvbutils
包裹。这foodweb
功能还是比较满意的。
回顾一下,我想了解如何检查一个包裹,比如说myPackage
与另一个相比,说externalPackage
,以及关于检查脚本externalPackage
。我将演示如何进行每一项操作。在这种情况下,外部包是data.table
.
1: For myPackage
versus data.table
,以下命令就足够了:
library(mvbutils)
library(myPackage)
library(data.table)
ixWhere <- match(c("myPackage","data.table"), search())
foodweb(where = ixWhere, prune = ls("package:data.table"), descendents = FALSE)
这会生成一个出色的图表,显示哪些函数依赖于中的函数data.table
。尽管图中包含了依赖关系data.table
,这并不太繁重:我可以很容易地看到我的哪些功能依赖于data.table
,以及他们使用哪些函数,例如as.data.table
, data.table
, :=
, key
, 等等。至此,可以说包依赖问题解决了,但是foodweb
提供了更多内容,让我们来看看。最酷的部分是依赖矩阵。
depMat <- foodweb(where = ixWhere, prune = ls("package:data.table"), descendents = FALSE, plotting = FALSE)
ix_sel <- grep("^myPackage.",rownames(depMat))
depMat <- depMat[ix_sel,]
depMat <- depMat[,-ix_sel]
ix_drop <- which(colSums(depMat) == 0)
depMat <- depMat[,-ix_drop]
ix_drop <- which(rowSums(depMat) == 0)
depMat <- depMat[-ix_drop,]
这很酷:它现在显示了我的包中函数的依赖关系,我在其中使用了详细的名称,例如myPackage.cleanData
,关于函数不
在我的包中,即函数data.table
,并且它消除了没有依赖性的行和列。这很简洁,让我可以快速调查依赖关系,并且通过处理,我也可以很容易地找到我的函数的补充集rownames(depMat)
.
NB: plotting = FALSE
似乎并没有阻止绘图设备的创建,至少在第一次foodweb
在一系列调用中被调用。这很烦人,但并不可怕。也许我做错了什么。
2:对于脚本与data.table
,这变得更有趣了。对于每个脚本,我需要创建一个临时函数,然后检查依赖关系。我下面有一个小函数可以做到这一点。
listFiles <- dir(pattern = "myScript*.r")
checkScriptDependencies <- function(fname){
require(mvbutils)
rawCode <- readLines(fname)
toParse <- paste("localFunc <- function(){", paste(rawCode, sep = "\n", collapse = "\n"), "}", sep = "\n", collapse = "")
newFunc <- eval(parse(text = toParse))
ix <- match("data.table",search())
vecPrune <- c("localFunc", ls("package:data.table"))
tmpRes <- foodweb(where = c(environment(),ix), prune = vecPrune, plotting = FALSE)
tmpMat <- tmpRes$funmat
tmpVec <- tmpMat["localFunc",]
return(tmpVec)
}
listDeps <- list()
for(selFile in listFiles){
listDeps[[selFile]] <- checkScriptDependencies(selFile)
}
现在,我只需要看看listDeps
,我也有与上面的 depMat 相同的奇妙的小见解。我修改了checkScriptDependencies
来自我编写的发送脚本进行分析的其他代码codetools::checkUsage
;有一个像这样的小函数来分析独立代码是很好的。感谢@太空人 https://chat.stackoverflow.com/transcript/message/2307138#2307138 and @Tommy https://stackoverflow.com/a/8773047/805808寻求改善通话的见解foodweb
, using environment()
.
(真正的匈牙利人会注意到我与名称和类型的顺序不一致 - 太糟糕了。:) 这样做有一个更长的原因,但这并不完全是我正在使用的代码。)
虽然我还没有发布生成的图表的图片foodweb
对于我的代码,您可以在以下位置看到一些很好的示例http://web.archive.org/web/20120413190726/http://www.sigmafield.org/2010/09/21/r-function-of-the-day-foodweb http://web.archive.org/web/20120413190726/http://www.sigmafield.org/2010/09/21/r-function-of-the-day-foodweb。就我而言,它的输出肯定捕获了 data.table 的用法:=
and J
,以及标准命名函数,例如key
and as.data.table
。它似乎避免了我的文本搜索,并且在几个方面都有所改进(例如查找我忽略的功能)。
总而言之,foodweb
是一个很棒的工具,我鼓励其他人探索mvbutils
包和 Mark Bravington 的其他一些不错的包,例如debug
。如果你安装了mvbutils
,只需查看?changed.funs
如果您认为只有您在管理不断发展的 R 代码方面遇到困难。 :)