【问题标题】:S3 generic/method consistency - How to dispatch according to chosen type?S3 泛型/方法一致性 - 如何根据选择的类型进行调度?
【发布时间】:2019-12-21 19:18:33
【问题描述】:

我正在尝试构建一个通用函数,该函数根据所选算法的类型分派给其他函数。在下面的示例中,算法类型仅由“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.

}

它可以工作,但是当我检查包时(使用 check()),我一直有同样的错误:

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.

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

【问题讨论】:

    标签: r devtools roxygen2


    【解决方案1】:

    在问题的代码中,MyFun 不是通用的,MyFun.algo1MyFun.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"
    

    【讨论】:

    • 这不能回答我的问题。你只是重新构建了我的代码,它做的事情完全一样。将你的函数 algo1 和 algo2 重命名为 Myfun.algo1 & Myfun.algo2 并运行 check(),你会看到,警告信息仍然存在。
    • 答案中的代码没有你遇到的问题,也避免了switch语句。当然,如果您将问题中的错误重新引入答案中,那么您当然会遇到同样的问题。
    • 我的问题是:为什么我不能命名我的函数 Myfun.algo1 & Myfun.algo2 ?你告诉我我不能,但你不告诉我为什么......例如看看基线包,这正是他们正在做的事情:有基线函数,然后是 basline.irls 等算法,你可以只需通过基线(x,方法=“irls”)调用它们。所以显然这是可能的。我应该将我的类型定义为一个类吗?
    • 大概检查看起来并不比名称更深,所以它认为你有一个 S3 泛型及其方法。只是不要使用那组名称。人们也很困惑——不仅仅是支票。
    • 没关系,我刚刚发现了这个问题:在不知道的情况下,我使用的函数名(MyFun)已经存在于 R 的基本包中......因此检查将我的论点与基本功能而不是我定义的新功能。我将 MyFun 的名称更改为 NewFun,现在我可以定义 NewFun.algo1 和 NewFun.algo2 如上所述...如果来自 devtools 的人阅读此内容,也许最好警告用户使用的函数名称已经存在于基本包......刚刚失去了12个小时。顺便感谢您的帮助和建议!
    猜你喜欢
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多