R中S3类的重载矩阵乘法
Posted
技术标签:
【中文标题】R中S3类的重载矩阵乘法【英文标题】:Overload matrix multiplication for S3 class in R 【发布时间】:2022-01-02 14:21:52 【问题描述】:如何重载R
中的矩阵乘法运算符?我已经能够使用大多数其他运算符(使用 Ops)来做到这一点,但是使用矩阵运算我得到了这个错误:
requires numeric/complex matrix/vector arguments
这是一个最小的工作示例:
speed = function(x)
structure(list(y = x),
class = "speed")
m = matrix(c(1,2,3,4), ncol = 2)
s = speed(m)
# Addition works fine
`+.speed` = function(e1, e2) e1$y + e2
s + 10
# But matrix multiplication doesn't
`%*%.speed` = function(e1, e2) e1$y %*% e2
s %*% c(1,2)
【问题讨论】:
如果'speed'是一个类,那么你不想定义'speed'函数。你可以考虑定义一个 as.speed 函数。 @42- 感谢反馈。更改构造函数的名称似乎并没有改变行为。 请注意,`%*%.speed`(s, c(1,2)) 确实有效。我对重载Primitive
s 不够熟悉,不知道如何使其工作。
@42- 我不同意,最好让构造函数反映类名(视情况而定)。
@KonradRudolph 好的,并承认 matrix
和 list
是我主张的很好的 R 反例。
【参考方案1】:
我认为这是因为 %*%
默认不是 S3 通用函数。你可以通过这样做来解决这个问题。
`%*%.default` = .Primitive("%*%") # assign default as current definition
`%*%` = function(x,...) #make S3
UseMethod("%*%",x)
`%*%.speed` = function(e1, e2) e1$y %*% e2 # define for speed
s %*% c(1,2)
[,1]
[1,] 7
[2,] 10
如果您想了解有关此here 的更多信息,可以查看 Hadley 的书
根据以下评论进行编辑。
【讨论】:
谢谢。我想知道%*%.default
= .Primitive("%*%") 是否比%*%.default
= %*%
更好。想法?
@dudu 我不应该认为这很重要,因为%*%
无论如何都会调用.Primitive
。很高兴被某人证明是错误的,但我不记得过去曾在类似情况下担心过,据我所知从未遇到过问题。
如果你的 sn-p 被多次执行似乎很重要。第二次,%*%.default will be defined as the S3 method instead of the .Primitive("%*%")
。以上是关于R中S3类的重载矩阵乘法的主要内容,如果未能解决你的问题,请参考以下文章