Во-первых, благодаря @ математическому .coffee я понял, как использовать пакет 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)
.
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
;хорошо иметь такую небольшую функцию для анализа автономного кода.Престижность @ 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. В моем случае его вывод определенно отражает использование data.table :=
и J
вместе сстандартные именованные функции, такие как key
и as.data.table
.Кажется, это устраняет мой текстовый поиск и является улучшением в нескольких отношениях (например, поиск функций, которые я упустил).
В общем, foodweb
- отличный инструмент, и я призываю других изучитьmvbutils
пакет и некоторые другие приятные пакеты Марка Брэвингтона, такие как debug
.Если вы устанавливаете mvbutils
, просто посмотрите ?changed.funs
, если считаете, что только вы боретесь с управлением развивающимся R-кодом.:)