Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 在R中使用sd作为泛型函数_Oop_R_R S3 - Fatal编程技术网

Oop 在R中使用sd作为泛型函数

Oop 在R中使用sd作为泛型函数,oop,r,r-s3,Oop,R,R S3,如果我有一个名为foo的类,那么可以直接重载summary函数 summary.foo = function(x, ...) print("bar") 但是,此技术不适用于sd函数,即 > bar = createFooClass() > sd.foo = function(x, ...) print("Hi") > sd(bar) error: is.atomic(x) is not TRUE 重载此函数的正确方法是什么?查看sd()的代码——它有效地在内部分派。换句

如果我有一个名为
foo
的类,那么可以直接重载
summary
函数

summary.foo = function(x, ...) print("bar")
但是,此技术不适用于
sd
函数,即

> bar = createFooClass()
> sd.foo = function(x, ...) print("Hi")
> sd(bar)
  error: is.atomic(x) is not TRUE

重载此函数的正确方法是什么?

查看
sd()
的代码——它有效地在内部分派。换句话说,它不是一个泛型函数,而是一个普通的旧正则函数


最简单的方法可能就是修改
sd()
以在类foo上分支

您需要为
sd
定义一个新的泛型

最简单的方法是使用S4,因为它会自动处理默认的“sd”方法:

setClass("foo", list(a = "numeric", names = "character"))

setGeneric("sd")

setMethod("sd", "foo", 
          function(x,  na.rm = FALSE){
              print("This is a foo object!")
              callNextMethod(x@a)
              })

tf <- new("foo", a = 1:10)
sd(tf)
#[1] "This is a foo object!"
#[1] 3.027650
setClass(“foo”,list(a=“numeric”,name=“character”))
setGeneric(“sd”)
setMethod(“sd”、“foo”,
函数(x,na.rm=FALSE){
打印(“这是一个foo对象!”)
callNextMethod(x@a)
})

tf您可以劫持任何非泛型函数,将其设置为(S3)泛型,并将原始版本设置为默认版本。例如:

## make an S3 generic for sd
sd <- function(x, ...) UseMethod("sd")
## take the usual definition of sd,
## and set it to be the default method
sd.default <- stats::sd
## create a method for our class "foo"
sd.foo = function(x, ...) print("Hi")
给予:

> args(sd.default)
function (x, na.rm = FALSE, ...) 
NULL
> args(stats::sd)
function (x, na.rm = FALSE) 
NULL
然后,这将提供所需的行为:

> bar <- 1:10
> sd(bar)
[1] 3.027650
> class(bar) <- "foo"
> sd(bar)
[1] "Hi"
>条形sd(条形)
[1] 3.027650
>等级(巴)标准差(巴)
[1] “嗨”

有趣的是,这在R扩展手册的编写部分有记录,我就是这么做的,但它似乎“错”了,而且有点尴尬。最好给R-devel发电子邮件,要求将
sd
(或者更好的,
var
)变成通用的。@hadley同意,但R Core需要维护这一点,在做一些通用的东西时,性能会受到影响,因此在R Ext.手册中有措辞和建议。我不相信这些借口。为什么说泛型而不是var?@hadley这不是我的借口;-)(我也同意你的看法)无论如何,在使用R Core之前,你会有点等待R Core实现它——因此“劫持”方法仍然是有价值的,直到R Core发布了一个稳定版本的R
sd()
作为一个泛型。很抱歉,我应该更清楚地表达我的意见-有时,在R-core实施明确需要的更改之前,您需要给他们一段艰难的时间。
> bar <- 1:10
> sd(bar)
[1] 3.027650
> class(bar) <- "foo"
> sd(bar)
[1] "Hi"