Apologies for the title, not sure how else to phrase this question.
If I want to create setMethod
on a class how can I distinguish between the similar cases of mat[i,]
and mat[i]
?
I know for the former I can use:
setMethod("[",
signature(x = "foo", j = "missing", drop = "missing"),
function(x,i,j,drop) return(myFunc(x,i))
)
How can I set a method to distinguish the latter where I wouldn't want to select rows but elements as in the base
matrix
class?
Looking at the ?[
documentation I expected something like the following would work:
setMethod("[",
signature(x = "foo", i = "numeric"),
function(x,i,j,drop) return(myFunc(x,i))
)
but it conflicts with any previously defined methods where j
and drop
are missing.
The idea being the same as
mat <- matrix(seq(9), 3, 3)
mat[c(1,3),]
1 4 7
3 6 9
mat[c(1,3)]
[1] 1 3
You will find a lot of examples in the Matrix package. It uses S4 and implements new classes and methods for matrices. As far as I know there is no way to declare what you are looking for in the signature. Instead you have to use the function nargs
to distinguish between mat[1]
and mat[1, ]
. Here is an example how to do that:
setClass("foo", slot = c(mat = "matrix"))
setMethod(
"[",
signature(x = "foo", i = "missing", j = "missing", drop = "missing"),
function(x, i, j, drop = FALSE) {
x
}
)
setMethod(
"[",
signature(x = "foo", i = "numeric", j = "missing", drop = "missing"),
function(x, i, j, ..., drop) {
if (nargs() == 3) x@mat[i, ]
else x@mat[i]
}
)
setMethod(
"[",
signature(x = "foo", i = "numeric", j = "numeric", drop = "missing"),
function(x, i, j, ..., drop) {
x@mat[i, j]
}
)
mat <- new("foo", mat = matrix(seq(9), 3, 3))
mat[]
mat[2:5]
mat[1:2, ]
mat[1:2, 2]
However, it would be easier if you directly extend the base class 'matrix' (or 'Matrix' from the Matrix package) and do something like
setClass("Matrix", contains = "matrix")
since you get these methods for free. Note for example, that in the implementation above, you still have to take care of the argument drop
. And basically you have to reimplement what is already there.
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