我可以列出包含'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
函数将被新附加的包中的一个掩盖。如果加载的函数是泛型函数(除非类名冲突,但这是另一个问题),这不是问题。但是,如果该函数不是通用函数,则加载包将是一个问题,我想要检测它。
答案 0 :(得分: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