Kar*_*ius 5 oop generics r class r-s3
我正在尝试将S3"Math"组泛型用于自定义类.但是我得到了一个奇怪的结果:log()同时工作log2并log10产生错误.以下是一个最小的例子:
# simple class with just the new name
lameclass <- function(x) {
class(x) <- append(class(x), "lame")
x
}
# It prints something when Math generics methods are used
Math.lame <- function(x, ...) {
print("I am lame")
NextMethod()
}
# an object of the class
lamevector <- lameclass(1:10)
> class(lamevector)
[1] "integer" "lame"
Run Code Online (Sandbox Code Playgroud)
现在试着打电话log:
log(lamevector)
[1] "I am lame"
[1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379 1.7917595 1.9459101 2.0794415 2.1972246 2.3025851
Run Code Online (Sandbox Code Playgroud)
基数为2:
log(lamevector, 2)
[1] "I am lame"
[1] 0.000000 1.000000 1.584963 2.000000 2.321928 2.584963 2.807355 3.000000 3.169925 3.321928
Run Code Online (Sandbox Code Playgroud)
以上都是有效的.但现在log2包装:
log2(lamevector)
[1] "I am lame"
[1] "I am lame"
Error in log2.default(1:10, 2) :
2 arguments passed to 'log2' which requires 1
Run Code Online (Sandbox Code Playgroud)
也许有人可以帮我搞清楚这里发生了什么?log2实际上经历了2次通用数学定义而失败了吗?
似乎发生的情况是,NextMethod没有剥离该类lame,因此当log2调用 时log,它会重新分派到该lame方法,该方法现在不再起作用,因为它正在调用log2,base = 2L而参数log2没有。
强制调度正常工作不需要太多工作\xe2\x80\x94只需剥离并重新添加类即可。(旁白:子类应该放在前面,而不是附加到后面。)
\n\n\n\nlameclass <- function(x) {\n class(x) <- c("lame", class(x)) # prepend new class\n x\n}\n\nMath.lame <- function(x, ...) {\n print("I am lame")\n class(x) <- class(x)[class(x) != "lame"] # strip lame class\n lameclass(NextMethod()) # re-add lame class to result\n}\n\nlamevector <- lameclass(1:5)\n\nlog(lamevector)\n#> [1] "I am lame"\n#> [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379\n#> attr(,"class")\n#> [1] "lame" "numeric"\nlog(lamevector, 2)\n#> [1] "I am lame"\n#> [1] 0.000000 1.000000 1.584963 2.000000 2.321928\n#> attr(,"class")\n#> [1] "lame" "numeric"\nlog2(lamevector)\n#> [1] "I am lame"\n#> [1] 0.000000 1.000000 1.584963 2.000000 2.321928\n#> attr(,"class")\n#> [1] "lame" "numeric"\nRun Code Online (Sandbox Code Playgroud)\n\n我不太清楚为什么会这样调度。组泛型有点奇怪,并且调度oldClass而不是class,这可能是也可能不是问题的一部分。这可能只是一个错误。剥离并重新添加类的习惯用法被用在其他Math方法中,可能是因为这个原因:
MASS:::Math.fractions\n#> function (x, ...) \n#> {\n#> x <- unclass(x)\n#> fractions(NextMethod())\n#> }\n#> <bytecode: 0x7ff8782a1558>\n#> <environment: namespace:MASS>\nRun Code Online (Sandbox Code Playgroud)\n