R:如何找到对象会调用什么 S3 方法?

标签 r methods

我知道methods() ,它返回给定类的所有方法。假设我有 x我想知道当我调用 foo(x) 时会调用什么方法.是否有可以做到这一点的oneliner或包裹?

我能想到的最短的是:

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

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

更新

完整的一个类轮将是:
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 , 调用foomatrix(1:4, 2, 2)会尝试foo.matrix ,然后 foo.numeric ,然后 foo.default ;而这段代码只会寻找 foo.matrixfoo.default .

最佳答案

findMethod下面定义的不是单行代码,但它的主体只有 4 行代码(如果我们要求将泛型作为字符串传递,它可以减少到 3 行代码)。它将返回一个字符串,表示将由输入泛型在给定泛型及其参数的情况下分派(dispatch)的方法的名称。 (如果您想返回方法本身,请将 findMethod 正文的最后一行替换为 get(X(...))。)在内部,它创建一个泛型 X 和一个对应于输入泛型的每个方法的 X 方法,这样每个 X 方法返回将要运行的输入泛型方法的名称。 X 泛型及其方法都在 findMethod 中创建。函数,所以它们在 findMethod 时消失退出。为了得到结果,我们只需运行 X 并将输入参数作为 findMethod 的最后一行。功能体。

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 给出了预期的结果。)
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 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42738851/

相关文章:

java - removeDuplicates 方法不会删除列表中的所有重复整数

r - R中治疗组和地点的多样性指数

r - 获取矩阵每一列中第一次出现值的索引

java - 如何将文件(带路径)作为Java中方法的参数传递

ios子类替代方案

java - 接口(interface)内的静态方法 - Java

javascript - 如何在 R 中的同一箱形图上绘制来自一个数据集的 2 组分类数据

r - 不断扫描 R 工作目录中的新文件

r - 在带有 NLME 对象和公式的函数调用中使用 predict

Java - 为什么 Eclipse 告诉我我的方法必须返回类型 int?