R:如何找到将在对象上调用的S3方法? [英] R: how to find what S3 method will be called on an object?

查看:158
本文介绍了R:如何找到将在对象上调用的S3方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know about methods(), which returns all methods for a given class. Suppose I have x and I want to know what method will be called when I call foo(x). Is there a oneliner or package that will do this?

我能想到的最短的是:

sapply(class(x), function(y) try(getS3method('foo', y), silent = TRUE))

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

and then to check the class of the results... but is there not a builtin for this?

更新

完整的一支班轮是:

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

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

This will work with most things but be aware that it might fail with some complex objects. For example, according to ?S3Methods, calling foo on matrix(1:4, 2, 2) would try foo.matrix, then foo.numeric, then foo.default; whereas this code will just look for foo.matrix and foo.default.

推荐答案

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

findMethod defined below is not a one-liner but its body has only 4 lines of code (and if we required that the generic be passed as a character string it could be reduced to 3 lines of code). It will return a character string representing the name of the method that would be dispatched by the input generic given that generic and its arguments. (Replace the last line of the body of findMethod with get(X(...)) if you want to return the method itself instead.) Internally it creates a generic X and an X method corresponding to each method of the input generic such that each X method returns the name of the method of the input generic that would be run. The X generic and its methods are all created within the findMethod function so they disappear when findMethod exits. To get the result we just run X with the input argument(s) as the final line of the findMethod function body.

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(...)
}

现在进行测试. (请注意,问题中的单行代码在其中一些测试中因错误而失败,但是findMethod提供了预期的结果.)

Now test it. (Note that the one-liner in the question fails with an error in several of these tests but findMethod gives the expected result.)

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"

这篇关于R:如何找到将在对象上调用的S3方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆