I am experimenting with S4 classes in R and I was trying to define a plus (+
) operator for my objects, i.e. overload the plus operator. I managed to overload the binary +
, but I cannot figure out how to overload the unary plus. Here is a minimal working (unary operator not working) example for what I am trying to achieve:
setClass("HWtest",
representation(expr = "character"),
prototype = list(expr = NA_character_)
)
H <- new("HWtest", expr="Hello")
W <- new("HWtest", expr="World")
setMethod("+", signature(e1="HWtest", e2="HWtest"),
function(e1,e2){
new("HWtest",
expr = paste(e1@expr," + ",e2@expr))
}
)
Now I can use the +
operator and it works smoothly:
H+W
An object of class "HWtest"
Slot "expr":
[1] "Hello + World"
Now the unary plus of course doesn't work, so that has to be overloaded
+H
Error in +H : invalid argument to unary operator
So I tried to overload it in the following way:
setMethod("+", signature(e="HWtest"),
function(e){
new("HWtest",
expr = paste("+ ",e@expr))
}
)
But this generates the error:
Error in match.call(fun, fcall) :
argument 1 matches multiple formal arguments
Is it possible to overload the unary plus? If so, how would I do it for this minimal example?
S4 class is defined using the setClass() function. In R terminology, member variables are called slots. While defining a class, we need to set the name and the slots (along with class of the slot) it is going to have.
The R parser doesn't support custom unary operators. A copy of the list of supported operators from the R language definition: - Minus, can be unary or binary + Plus, can be unary or binary ! Unary not ~ Tilde, used for model formulae, can be either unary or binary ?
More specifically, S4 has setter and getter functions for methods and generics. As compared to the S3 class, S4 can be able to facilitate multiple dispatches. Let us see the above-discussed classes of R by creating them and discuss with an example. An S4 class is defined using the set class function.
The S3 and S4 software in R are two generations implementing functional object-oriented programming. S3 is the original, simpler for initial programming but less general, less formal and less open to validation. The S4 formal methods and classes provide these features but require more programming.
Try adding this (in addition to your binary overload):
setMethod("+", signature(e1 = "HWtest", e2 = "missing"),
function(e1){
new("HWtest",
expr = paste("+ ", e1@expr))
}
)
R> +H
An object of class "HWtest"
Slot "expr":
[1] "+ Hello"
R> H + W
An object of class "HWtest"
Slot "expr":
[1] "Hello + World"
Citing the help file ?groupGeneric
,
[...] when a unary operator is encountered the Ops method is called with one argument and e2 is missing.
And as Frank points out, the ?setMethod
help file contains some useful information regarding the use of missing
as a method signature (emphasis added):
Two additional special class names can appear: "ANY", meaning that this argument can have any class at all; and "missing", meaning that this argument must not appear in the call in order to match this signature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With