R:如何找到将在对象上调用的S3方法?

4 methods r

我知道methods(),它将返回给定类的所有方法。假设我有x并且想知道在调用时将调用哪种方法foo(x)。是否有可以做到这一点的内衬或包装?

我能想到的最短的是:

sapply(class(x), function(y) try(getS3method('foo', y), silent = TRUE))
Run Code Online (Sandbox Code Playgroud)

然后检查结果的类...但是没有内置函数吗?

更新资料

完整的一个班轮是:

fm <- function (x, method) { 
  cls <- c(class(x), 'default')
  results <- lapply(cls, function(y) try(getS3method(method, y), silent = TRUE))
  Find(function (x) class(x) != 'try-error', results)   
}
Run Code Online (Sandbox Code Playgroud)

这适用于大多数情况,但请注意,对于某些复杂的对象它可能会失败。例如,根据?S3Methods,呼吁foomatrix(1:4, 2, 2)会尝试foo.matrix,然后foo.numeric,然后foo.default,而此代码只会查找foo.matrixfoo.default

G. *_*eck 7

findMethod下面定义的不是单行代码,而是它的主体只有4行代码(如果我们要求将泛型作为字符串传递,则可以简化为3行代码)。给定泛型及其参数,它将返回一个字符串,该字符串表示输入泛型将分派的方法的名称。(如果要返回方法本身,请替换findMethodwith 的最后一行get(X(...))。)在内部,它会创建泛型X和与输入泛型的每个方法相对应的X方法,以便每个X方法都返回该方法的名称。将要运行的输入泛型。X泛型及其方法都在findMethod函数中创建,因此它们在出现时消失findMethod退出。为了获得结果,我们只需使用输入参数作为findMethod函数主体的最后一行来运行X。

findMethod <- function(generic, ...) {
  ch <- deparse(substitute(generic))
  f <- X <- function(x, ...) UseMethod("X")
  for(m in methods(ch)) assign(sub(ch, "X", m, fixed = TRUE), "body<-"(f, value = m))
  X(...)
}
Run Code Online (Sandbox Code Playgroud)

现在测试一下。(请注意,问题中的一种方法在其中一些测试中findMethod因错误而失败,但给出了预期的结果。)

findMethod(as.ts, iris)
## [1] "as.ts.default"

findMethod(print, iris)
## [1] "print.data.frame"

findMethod(print, Sys.time())
## [1] "print.POSIXct"

findMethod(print, 22)
## [1] "print.default"

# in this example it looks at 2nd component of class vector as no print.ordered exists
class(ordered(3))
## [1] "ordered" "factor" 
findMethod(print, ordered(3))
## [1] "print.factor"

findMethod(`[`, BOD, 1:2, "Time")
## [1] "[.data.frame"
Run Code Online (Sandbox Code Playgroud)