问题
I am developing a package and want to write two subset methods for objects of a custom class, myclass
, with dispatch on two arguments, first one being the object to subset, of class myclass
, and the second being either logical of character vector, like so:
setMethod(
f = "subset",
signature = c(x = "myclass", subset = "logical"),
definition = function(x, subset){
# function body
}
)
setMethod(
f = "subset",
signature = c(x = "myclass", subset = "character"),
definition = function(x, subset){
# different function body
}
)
However, I cannot do this because the S3 generic dispatches on one argument only. And I don't want to create a new generic for subset
because it would mask the existing generic when my package is loaded.
One way around this issue, I think, would be to create a generic and methods of different name, but this would not be very intuitive for the users, right?
So am I missing/misunderstanding something, and is there any witty way to have multiple dispatch for S3 generics?
回答1:
Normally in this situation you would set subset
as an S4 generic but since you have reasons for not wanting to do that, you can get around this by defining a separate generic and calling it from within the S3 method, along the lines of
mySubset <- function(x,subset){
stop("this is only a generic function: it should never be called!")
}
setGeneric("mySubset")
## methods for mySubset
setMethod(
f = "mySubset",
signature = c(x = "myclass", subset = "logical"),
definition = function(x, subset){
# function body
}
)
setMethod(
f = "mySubset",
signature = c(x = "myclass", subset = "character"),
definition = function(x, subset){
# different function body
}
)
## default method using "ANY" (lower priority)
setMethod(
f = "mySubset",
signature = c(x = "myclass", subset = "ANY"),
definition = function(x, subset){
## insert default behaviour (might be an error),
## a call to subset.default or whatever
}
)
## now write an S3 method for subset that calls the S4 generic if
## x is of class myclass
subset.myClass <- function(x,subset){
mySubset(x,subset)
}
This preserves the S3-only behaviour of subset, but you now have S4 level control over method dispatch provided that x
is of class myclass
.
Your users don't need to appreciate this distinction; they can still call subset(x,class)
in the same way they are accustomed to, when x
has your new class.
来源:https://stackoverflow.com/questions/49346939/multiple-dispatch-for-subset-methods-in-r