如何不覆盖泛型方法

How not to overwrite generic methods

提问人:Stephen Lien 提问时间:7/1/2014 最后编辑:Konrad RudolphStephen Lien 更新时间:9/4/2020 访问量:756

问:

我正在尝试了解 R 中的 s3 类系统。

文档说我需要为我要创建的方法创建一个泛型函数。

假设我想为类 XYZ 创建一个方法 foo

使用 R 拥有的所有包,我如何确定我没有覆盖以前创建的泛型方法?

Summary 是一个不好的例子,因为每个人都可能知道它已经存在,但是我的泛型可能已经在我已经加载的包或我将要加载的包中定义了。

R OOP 方法 R-S4 R-S3

评论

2赞 Roman Luštrik 7/1/2014
问题不在于方法,而在于类。如果你的类与其他包不同,其余的就变得微不足道了。
0赞 Roland 7/1/2014
主要问题不是覆盖泛型(尽管这也可能导致问题),而是屏蔽非泛型,例如(泛型)掩码(非泛型)。关于来自其他包的屏蔽方法,这通常是可以避免的,因为不难找到一个可能是唯一的类名(例如,如果不是 lme4 作者,谁会调用一个类)。dplyr::filterstats::filtermerMod
2赞 Stephen Lien 7/20/2014
让我们以泛型摘要为例,并假设我不知道 R 摘要中的某个地方已被定义为泛型。如果我创建摘要 <- function() usemethod(“summary”),这将破坏 GLM 对象的摘要。有没有办法定义泛型,这样它就不会破坏也可能定义它的对象。如果我将其定义为摘要 <- function(x) UseMethod(“summary”),虽然它适用于 summary(glm( )) 的基本情况,但它现在中断了,summary(glm(, dispersion=10))。
0赞 Tommy O'Dell 3/16/2015
您可以通过添加指向原始函数的默认方法,在不破坏原始函数的情况下将函数重新定义为泛型函数。请参阅此处的要点 gist.github.com/datalove/88f5a24758b2d8356e32
0赞 Konrad Rudolph 9/4/2020
@RomanLuštrik 只有当您的包裹没有附加时,这才是正确的。附加包后,泛型可能会覆盖其他现有函数(反之亦然)。这绝对是 R 包系统中的一大缺陷。

答:

0赞 hamagust 9/2/2020 #1

我遇到过类似的问题,我想在这里发布一个部分解决方案,并在此过程中吸取一些教训。

  • 我不确定问题是否真的是 S3 方法覆盖了通用方法,而是非 s3 方法(我已经发现了一些问题,在发送 s4 方法和包时失败)。summarylavaansemTool
  • 我们可以通过或所有方法检查可用的方法 对于类。methods("foo")methods(class="XYZ")
  • 我们可以检查泛型是否已经注册。isGeneric("foo")

如果方法尚未注册,那么,我们需要设置一个泛型使用(不是这种情况):summary

foo<- function(x) UseMethod("foo")

第一个问题是:

  1. 我们能够看到仅针对已加载包的方法;
  • 有选项,但它需要函数和类;getS3method(f="foo",class="XYZ")

  • utils::getAnywere("foo")更广泛,而且,仅适用于加载的包......

如果只存在 S3方法(没有 S4method),这不是真正的问题,并且我们没有指定泛型方法,而只是指定新方法,并且我们确定类名尚未使用。


第二个问题是:

  1. 如果该函数还关联了一个 S4 方法,显然,通过指定新的 s3 方法(即使与已经存在的泛型,如 的情况一样),它会弄乱向 S4 方法的发送summary
  • 目前,我看到的唯一解决方案是为每个已识别的 s4 方法创建一个新的 s3 方法......

(i) 因此,我们也可以专门跟踪特定类的 S3 方法或 s3 方法,并在加载所有主要包后专门找出 S4 方法(例如使用),我担心......;.S3methods("foo").S3methods(class="XYZ").S4methods("foo")

(ii) 确定对象类别;

(iii) 检查其文档中是否有任何相应的方法(显然,某些 S4 方法在文档中不太容易识别,因此在 S3Method 中很容易调用)

(iv) 如果 (iii) 不可用,则评估其结构;和

(v) 通过调用已识别的方法(如果可用)或从对象中提取所需的输出,为特定类指定相应的 S3 方法,同时考虑其结构......

(使用 .default 是一种替代方案,但我想需要仔细考虑)。

但是,尽管考虑类对象结构重新指定方法的替代方案对于方法来说更容易一些,但对于其他函数来说,这可能是一项非常艰巨的工作......summary

我想应该有一个广泛的解决方案来自动考虑 s4 方法,但我对 S4methods 的有限知识目前无法发展......