Shixiang Wang
Shixiang Wang

Reputation: 2391

How to reuse infix operators like %*% and %x% into package for S3 method dispath?

I have a question about using R infix operator including %*% etc.

For overloading + operator for a custom class, I can use

#' @export
`+.custom` = function(x, y) ...

However, similar ways cannot be applied to %*% or other operators starts and ends with %. I googled many sites and found nothing useful to solve this.

Any suggestions?

An example given below.

r$> x = 1:5                                                                                                             
r$> y = 6:10                                                                                                            
r$> class(x) = "custom"                                                                                                 
r$> class(y) = "custom"                                                                                                 
r$> x + y                                                                                                               
[1]  7  9 11 13 15
attr(,"class")
[1] "custom"

r$> `+.custom` = function(x, y) return(as.numeric(x) + as.numeric(y) + 1)     
r$> `%*%.custom` = function(x, y) return(as.numeric(x) + as.numeric(y) + 1)                                             
r$> x %*% y  # Here the `%*%` function from base package is used                                                                                                        
     [,1]
[1,]  130
r$> `%*%.custom`(x, y)                                                                                                  
[1]  8 10 12 14 16

It seems the %*% don't support S3method dispatch.

I can solve this by overwriting %*% in my package with manually dispatch, like

r$> `%*%` = function(x, y) if (any(class(x) %in% "custom")) return(as.numeric(x) + as.numeric(y) + 1) else base::`%*%`(x
    , y)                                                                                                                

r$> x %*% y                                                                                                             
[1]  8 10 12 14 16

r$> as.numeric(x) %*% as.numeric(y)                                                                                     
     [,1]
[1,]  130

However, I prefer the first way like +.

Upvotes: 1

Views: 12

Answers (0)

Related Questions