【问题标题】:Extending apply function to S3 (like with print or plot)将应用功能扩展到 S3(如打印或绘图)
【发布时间】:2018-09-09 17:17:53
【问题描述】:

我正在使用 R 中的 pet project 构建一个名为 groupr 的自定义 S3 类。我已经编写了一些带有点符号的函数(print.grouprsubset.groupr),如 Hadley tutorial 中所述,但我希望喜欢扩展 apply 函数并且找不到方法这样做。

如教程中所示,pryr 包提供了提示。我看到 subsetprint 函数是不同的函数类型,如下所示:

> pryr::ftype(subset)
[1] "s3"      "generic"
> pryr::ftype(apply)
[1] "function"

另外,subset 函数会在终端中打印:

function (x, ...) 
UseMethod("subset")
<bytecode: 0x115f0ab88>
<environment: namespace:base>

apply 函数会打印其整个源代码。我相信我明白为什么会发生这种情况 - printsubsetplot 等函数是 S3 函数,而 apply 是一个无聊的旧正常函数 - 但我不知道查看任何扩展 apply 函数而不“覆盖”基本函数的方法。例如,UseMethod("apply") 在加载包时将函数调用指向我的groupr 命名空间。

有谁知道如何解决这个问题?也就是说,apply 函数族不是 S3 对象,不能使用点表示法进行扩展。有谁知道如何编写apply.myclassapply.myotherclass 函数?

【问题讨论】:

  • apply 不是通用的。我相信这就是区别所在,为它编写方法应该很尴尬。就像你说的,你必须“覆盖”基本函数

标签: r oop apply lapply r-s3


【解决方案1】:

你大部分时间都在那里;您确实需要覆盖原始的apply,但使用一个将原始函数调用为默认值的通用函数。因此,您的包将具有三个功能:apply,它将是新的泛型,apply.default,它将调用base::apply,以及您的新apply.myclass。当你的包被加载时,你的apply 版本在搜索路径中会更高,所以会被使用。我确信我已经看到包这样做了,但我现在不能举一个例子。

不过,我会质疑这是否值得;例如,您的用户真的会介意groupr 的版本是apply_groupr 吗?我们都知道apply 做了什么,并且在矩阵上使用了,这个新功能真的足够相似,可以共享相同的名称吗?那就是如果我看到apply(my_groupr, 2, mean) 会不会因为my_groupr 不是矩阵而感到困惑?

【讨论】:

  • 酷,我相信这是有道理的。我的计划本质上就是您所描述的 - 给它一个完全不同的名称 - 因为它避免了搜索路径的废话。但是,在我看来,apply 确实足够通用,可以将其重写为 S3 通用函数。例如,apply.matrixapply.listapply.vector 可以替换 applylapplyvapply。这只是一种矢量化的循环方式。我想这只是我第一次遇到 R 本身的奇怪特性(另一个是点符号的不一致应用,例如 t.data.frame
  • 说到R的怪异特质,你见过The R Inferno吗?
  • that,是的,我看过但还没有通读。似乎有人对这些东西有幽默感。
猜你喜欢
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多