递归S3调用包

时间:2017-12-07 15:52:28

标签: r recursion r-package r-s3

我想要完成的事情

我有一个带有一些内部R函数的R包(在下面的例子中称为f和g),它们以递归方式使用。在最小的示例中,函数只返回其参数的长度,但在实际代码中,它们会触发更复杂的计算。

我想做的是以下内容:

  1. 如果用户将对象传递给函数g,则R应该查找是否有我们可以调用此对象的S3方法。

  2. 如果对象是列表,则应将函数g应用于列表中的每个对象。如果我们还没有达到最大递归深度,请转到1.如果我们达到最大递归级别停止。

  3. 显示问题的代码

    将以下代码放入包中非常重要。如果代码是包的一部分,我得到的错误只能重现。

    utils.R

    g <- function(x, depth = 0) {
      stopifnot(depth <= 1)
      UseMethod("g")
    }
    
    g.numeric <- function(x, depth = 0) {
      length(x)
    }
    
    g.integer <- function(x, depth = 0) {
      length(x)
    }
    
    g.double <- function(x, depth = 0) {
      length(x)
    }
    
    g.list <- function(x, depth = 0) {
      sum(sapply(x, g, depth = depth + 1))
    }
    

    core.R

    #' @export
    core_fun <- function(x) {
      g(x)
    }
    

    我的期望

    错误

    结果应为6;

    x <- c(1.0, 1.3, 1.5)
    core_fun(list(x,x))
    

    但是我收到一条错误消息:

    Error in UseMethod("g") : 
    no applicable method for 'g' applied to an object of class "c('double','numeric')"  
    

    通行证

    结果应为3.

    x <- c(1.0, 1.3, 1.5)
    core_fun(x)
    

    说明

    当我调用该示例时,失败,在将函数g加载到全局命名空间后,我得到了预期的结果,6。

    所以我认为这是一个与命名空间/ S3相关的问题,但我不知道如何修复它。

1 个答案:

答案 0 :(得分:2)

我认为这与?lapply中的此注释有关。如果您按照他们的建议使用包装器运行它,则调度将正确完成。

g.list <- function(x, depth = 0) {
  sum(sapply(x, function(x_i) g(x_i, depth = depth + 1)))
}

enter image description here