R S3通用/方法一致性-如何根据所选类型进行调度?

R S3通用/方法一致性-如何根据所选类型进行调度?,r,devtools,roxygen2,R,Devtools,Roxygen2,我试图构建一个通用函数,根据所选算法的类型将其分派给其他函数。在下面的示例中,算法的类型仅由“algo1”、“algo2”等字符选择。。。x是S4类的对象。参数A和B对于所有方法(函数)都是通用的。我想把函数命名为Myfun.algo1和Myfun.algo2。这些函数将一些参数设置为一些默认值,因此具有泛型 #' @export Myfun Myfun<-function(x, type = c("algo1", "algo2"), A, B, ...){ switch(type,

我试图构建一个通用函数,根据所选算法的类型将其分派给其他函数。在下面的示例中,算法的类型仅由“algo1”、“algo2”等字符选择。。。x是S4类的对象。参数A和B对于所有方法(函数)都是通用的。我想把函数命名为Myfun.algo1和Myfun.algo2。这些函数将一些参数设置为一些默认值,因此具有泛型

#' @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.

}

我查阅了手册,但它确实没有什么帮助。我尝试通过添加@method和@S3method来更改roxygen2标签,但没有任何帮助。我试着改变了。。。把“类型”放在MyFun的末尾,也没用。我不明白。。。我做错了什么?为什么不允许我这样做?有办法解决这个问题吗?

问题中的代码
MyFun
不是通用的,而且
MyFun.algo1
MyFun.algo2
不是S3方法,尽管名称似乎暗示了这一点。最好把它改成这样,它不会暗示它不是什么,不会触发任何检查,而且更紧凑

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"

Myfun不能回答我的问题。你只是重新构造了我的代码,它做了完全相同的事情。将函数algo1和algo2重命名为Myfun.algo1&Myfun.algo2并运行check(),您将看到警告消息仍然存在。答案中的代码没有您遇到的问题,并且避免了switch语句。当然,如果你在答案中重新引入问题中的错误,那么你当然会遇到同样的问题。我的问题是:为什么我不能将我的函数命名为Myfun.algo1和Myfun.algo2?你告诉我我不能但你不告诉我为什么。。。例如,看看基线包,这正是他们正在做的:有基线函数,然后是basline.irls等算法,您可以通过执行基线(x,method=“irls”)来调用它们。显然这是可能的。我应该将我的类型定义为一个类吗?大概检查的深度不会超过名称,因此它认为您有一个S3泛型及其方法。只是不要用那套名字。这对人们来说也是相当混乱的——不仅仅是检查。别担心,我刚刚解决了问题:在不知道的情况下,我使用了一个函数名(MyFun),它已经存在于R的基本包中。。。因此,检查是将我的参数与基函数的参数进行比较&而不是我定义的新函数。我将MyFun的名称改为NewFun,现在我可以定义NewFun.algo1和NewFun.algo2,如上所述。。。如果来自devtools的人读到了这篇文章,那么最好警告用户所使用的函数名已经存在于基本包中。。。在这件事上损失了12个小时。顺便谢谢你的帮助和建议!
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"