Поиск всех существующих функций для зависимостей пакетов? - PullRequest
11 голосов
/ 22 марта 2012

У меня есть пакет, который я написал во время изучения R, и его список зависимостей довольно длинный.Я пытаюсь урезать его, для двух случаев:

  1. Я переключился на другие подходы, и пакеты, перечисленные в Suggests, просто не используются вообще.
  2. Толькоодна функция из всего моего пакета зависит от заданной зависимости, и я хотел бы переключиться на подход, где она загружается только при необходимости.

Есть ли автоматизированныйспособ отследить эти два случая?Я могу придумать два грубых подхода (загрузить список функций во всех зависимых пакетах и ​​автоматизировать текстовый поиск их по коду моего пакета или загрузить функции пакета без загрузки требуемых пакетов и выполнять до появления ошибки), но никажется особенно элегантным или надежным ...

1 Ответ

1 голос
/ 22 марта 2012

Одним из способов проверки зависимостей во всех функциях является использование байтового компилятора, поскольку он проверит наличие функций в глобальном рабочем пространстве и выдаст уведомление, если не найдет указанную функцию.

Так что если выНапример, используйте функцию na.locf из пакета zoo в любой из ваших функций, а затем побайтно скомпилируйте свою функцию, вы получите сообщение, подобное этому:

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))

Затем запустите R без предварительно загруженных пакетов и исходного кода в C: \ SomeLibrary.r

А затем вы должны получить заметки из cmpfun для любого вызова функции в пакете, который не является частью базовых пакетов и для которого не определено полностью определенное пространство имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...