首先,感謝@ mathematicalcoffee讓我走上了使用Mark Bravington的mvbutils
包的道路。 foodweb
功能更令人滿意。回顧一下,我想知道關於檢查一個軟件包,比如說myPackage
與另一個軟件包比較,比如說externalPackage
,以及關於檢查腳本與externalPackage
。我將演示如何做每個。在這種情況下,外部包是data.table
。
1:對於myPackage
與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)
,我也可以輕鬆地爲我的功能找到補充集。
注意: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
分析的腳本;有這樣一個小功能來分析獨立代碼是很好的。感謝@Spacedman和@Tommy的洞察力,改善了對foodweb
的調用,使用environment()
。
(真正的hungaRians會注意到我與名稱和類型的順序不一致 - tooBad。:)有更長的理由,但這不完全是我使用的代碼。)
雖然我還沒有張貼foodweb
我的代碼生成的圖形的圖片,你可以在http://web.archive.org/web/20120413190726/http://www.sigmafield.org/2010/09/21/r-function-of-the-day-foodweb看到一些很好的例子。在我的情況下,其輸出明確捕獲了數據表的使用:=
和J
,以及標準的命名函數,如key
和as.data.table
。它似乎消除了我的文本搜索,並且在幾個方面有所改進(例如,查找我忽略的功能)。
總而言之,foodweb
是一個很好的工具,我鼓勵其他人去探索mvbutils
包和一些Mark Bravington的其他不錯的包,比如debug
。如果你確實安裝了mvbutils
,只需要檢查?changed.funs
,如果你認爲只有你努力管理不斷髮展的R代碼。 :)
你可以嘗試包'mvbutils''' foodweb'嗎?我自己沒有經驗,但對我來說似乎很有前景(除了我不知道它搜索到多深)。就像'foodweb(where ='package:data.table',prune ='function_youre_examining')''? – 2012-01-07 01:00:37
@ mathematical.coffee這非常有趣。它看起來是非常有用的內部包裝;我還不清楚它可以做什麼,但我會給它一個旋轉,謝謝! – Iterator 2012-01-07 04:00:18
@ mathematical.coffee這非常有趣。我正在進一步阻止它。你可以發表你的評論作爲答案?我可以幫助將它編輯成解決方案,假設我能夠實現它。我以前評論說,它似乎並沒有跨軟件包工作,但這是不正確的。 「where」參數似乎在管理搜索空間方面起到了訣竅的作用。順便說一下,對於changed.funs的幫助幾乎和我最近的一些經歷一樣。 :) – Iterator 2012-01-07 04:41:47