Как проверить, является ли функция в пакете R общей или нет - PullRequest
0 голосов
/ 01 июня 2018

Я могу перечислить все пакеты, содержащие функцию 'auc':

library(sos)
library(dplyr)

auc.search = findFn("auc") 
auc.search %>%
    filter(Function == "auc", Package != "pROC") %>%
    select(Package, Function, Description) %>% head

          Package Function                                                  Description
1         longROC      auc                                                          AUC
2             AUC      auc   Compute the area under the curve of a given performance...
3              PK      auc Estimation of confidence intervals for the area under the...
4 PresenceAbsence      auc                                         Area Under the Curve
5            aucm      auc                                                          AUC
6         precrec      auc                          Retrieve a data frame of AUC scores

Теперь я хочу проверить, являются ли функции в этих пакетах общими функциями или нет.Как я могу это сделать?

Например, я хочу что-то вроде этого:

library(AUC)
is.generic(AUC::auc)
FALSE

library(pROC)
is.generic(pROC::auc)
TRUE

Немного предыстории о причине, по которой я делаю это: когда я загружаю любой из этих пакетов, мойФункция auc в пакете на пути поиска будет маскироваться функцией из вновь прикрепленного пакета.Это не проблема, если загруженная функция является универсальной (если имена классов не конфликтуют, но это другой вопрос).Однако, если функция не является общей, загрузка пакета будет проблемой, которую я хочу обнаружить.

1 Ответ

0 голосов
/ 03 июня 2018

Следующая функция в основном выполняет свою работу.Он использует utils::isS3stdGeneric, указанный @Gregor для проверки обобщений S3, и methods::isGeneric для S4.Основная проблема заключается в том, что он должен испортить пространство поиска, поэтому большая часть функции фактически загружает пакет и обеспечивает его корректное удаление с последующими зависимостями.

is.function.in.package.generic <- function(pkg, fun) {
    old.search.pos <- search()[2]
    on.exit({
        while (attr(parent.env(.GlobalEnv), "name") != old.search.pos) {
            detach()
        }
    })
    suppressPackageStartupMessages(library(pkg, character.only = TRUE))
    # Does the package actually have a roc function
    t <- try(get(fun), silent=TRUE)
    if (methods::is(t, "try-error")) {
        warning(sprintf("Package %s doesn't seem to contain function %s", pkg, fun))
        return(NA)
    }
    if (isS3stdGeneric(fun)) {
        return(TRUE)
    }
    if (isGeneric(fun)) {
        return(TRUE)
    }
    return(FALSE)
}

Кажется, что он работает нормально:

> is.function.in.package.generic("graphics", "plot") #S4
[1] TRUE
> is.function.in.package.generic("analogue", "roc") #S3
[1] TRUE
> is.function.in.package.generic("longROC", "roc") # Not generic
[1] TRUE
> is.function.in.package.generic("aucm", "roc") # No such function
[1] NA
Warning message:
In is.function.in.package.generic("aucm", "roc") :
  Package aucm doesn't seem to contain function roc
...