Reputation: 663
I am trying to build a generic function that dispatches to other functions according to the type of algorithm chosen. In the example below, the type of algorithm is just chosen by a character like "algo1", "algo2", etc... x is an object of class S4. Arguments A & B are common to all methods (functions). I'd like to name the functions called Myfun.algo1 and Myfun.algo2. These functions have some parameters set to some default value, hence the purpose of having a generic.
#' @export Myfun
Myfun<-function(x, type = c("algo1", "algo2"), A, B, ...){
switch(type,
algo1={res<-do.call(Myfun.algo1, list(x, A, B, ...))},
algo2={res<-do.call(Myfun.algo2, list(x, A, B, ...))},
stop("Unknown Type"))
return(res)
}
#' @rdname MyFun
#' @export
MyFun.algo1<-function(x, A, B, C=2, D=300){
#Do a bit of magic.
}
#' @rdname MyFun
#' @export
MyFun.algo2<-function(x, A, B, E=10, F=1000){
#Do more magic.
}
It works but when I check the package (with check()), I keep having the same error:
checking S3 generic/method consistency ... WARNING MyFun: function(x, type, A, B, ...) MyFun.algo1: function(x, A, B, C, D) #Same thing for algo2. See section 'Generic functions and methods' in the 'Writing R Extensions' manual. Found the following apparent S3 methods exported but not registered: MyFun.algo1 MyFun.algo2 See section 'Registering S3 methods' in the 'Writing R Extensions' manual.
I looked into the manual but it was really not helpful. I tried changing the roxygen2 tags by adding @method and @S3method, it didn't helped. I tried changing the order of the ... and put "type" at the end in MyFun, it didn't helped neither. I don't understand... what am I doing wrong? Why am I not allowed to do this ? Is there a way around this?
Upvotes: 2
Views: 439
Reputation: 270448
In the code in the question MyFun
is not a generic and MyFun.algo1
and MyFun.algo2
are not S3 methods even though the names seem to suggest that. It would be beter to change it to something like this which is not suggestive of something it is not, won't trigger any checks and is more compact.
Myfun <- function(x, type = c("algo1", "algo2"), A, B, ...) {
type <- match.arg(type)
do.call(type, list(x, A, B, ...))
}
algo1 <- function(x, A, B, ...) "algo1"
algo2 <- function(x, A, B, ...) "algo2"
# test run
Myfun(1, "algo1", 2, 3)
## [1] "algo1"
# another test run
Myfun(1, A = 2, B = 3)
## [1] "algo1"
Upvotes: 2