【问题标题】:How to test if a function in an R package is generic or not如何测试 R 包中的函数是否是通用的
【发布时间】:2018-06-01 16:22:22
【问题描述】:

我可以列出所有包含“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 函数将被新附加包中的函数所掩盖。如果加载的函数是泛型的,这不是问题(除非类名冲突,但这是另一个问题)。但是,如果函数不是泛型的,加载包将是一个问题,我想检测一下。

【问题讨论】:

  • 好吧,isGeneric 内置在 methods 包中,但我似乎无法让它工作......
  • @Gregor 我相信它只适用于 S4 方法,就像方法包中的所有内容一样,令人困惑。这个包的标题是“Formal Methods and Classes”,也就是S4。
  • 啊,但一个愉快的自动完成意外将我指向utils::isS3stdGeneric,这似乎是您所追求的(或至少非常接近)。
  • @Gregor 谢谢这很有用。我写了一个有效的答案,但我很乐意接受一个不会弄乱搜索空间的答案。

标签: r generics methods package


【解决方案1】:

以下函数基本上完成了这项工作。它使用@Gregor 指出的utils::isS3stdGeneric 来测试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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-27
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 2014-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多