微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何覆盖 R

如何解决如何覆盖 R

在 R 中,我有一个模拟一维向量的 S3 类,所以我想实现 meansummax 等的自定义版本。假设它看起来像像这样:

my_class = function(){
  structure(list(),class='my_class')
}

以上所有方法都可以正常工作,如果我定义了 mean.my_class 等:

mean.my_class = function(x){
  2
}

mean(my_class())

但是,我也想对 var 之类的函数执行此操作,它不是通用方法。如果我创建这样一个函数,然后在我的类的一个实例上调用 var

var.my_class = function(his){
  # Do stuff here
}

var(my_class())

我收到错误

Error in var(my_class()) : is.atomic(x) is not TRUE

这是因为没有通用的 var 函数,它只是在我的结构上调用 stats::var。如果没有通用方法,我如何提供自定义实现?我也不想破坏常规向量的 var 方法

解决方法

您可以使用与现有非泛型函数相同的名称和签名创建自己的泛型:

var = function (x,y = NULL,na.rm = FALSE,use) UseMethod('var')
var.my_class = function (x,y,na.rm,use) 42

registerS3method('var','default',stats::var)
registerS3method('var','my_class',var.my_class)

... 而不是手动复制泛型函数的形式参数列表,您可以改为使用以下内容自动生成它:

var = function () UseMethod('var')
formals(var) = formals(stats::var)

——当然,以上只有在调用者调用您的 var 函数时才有效。如果有人调用 stats::var 实例,则不会找到您的泛型,因此不会发生 S3 方法调度。


请注意,R 3.5 改变了 S3 方法查找跨环境的工作方式,仅定义适当命名的函数已不足以从不同的环境中找到该方法 - 您需要调用 registerS3method(不仅适用于 var 这样的新泛型,还适用于您的 mean!)。不幸的是,这个函数几乎没有官方文档,只有一些blog posts by Kurt Hornik

,

methods for non generics 开始,S4 setMethod 似乎与 S3 类兼容:

setMethod("var","my_class",function(x,use) {"Var for my_class"})
#> Creating a generic function for 'var' from package 'stats' in the global environment
#> in method for 'var' with signature '"my_class"': no definition for class "my_class"

my_class = function(){
  structure(list(),class='my_class')
}

var(my_class())
#> [1] "Var for my_class"
var(1:10)
#> [1] 9.166667

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。