代码之家  ›  专栏  ›  技术社区  ›  David Locke

如何使用函数参数而不在函数体中提及它?

r
  •  7
  • David Locke  · 技术社区  · 16 年前

    我一直在尝试了解更多关于R(和编写C扩展)的信息,我认为阅读一些知名软件包的源代码可能会有所帮助。我决定从定义为:

    rpart <- function(formula, data, weights, subset,
           na.action=na.rpart, method, model=FALSE, x=FALSE, y=TRUE,
           parms, control, cost, ...)
    

    我快速搜索了源代码,在函数体的任何地方都看不到提到的公式,但我知道不知何故rpart使用了这个参数。rpart是如何使用不在函数体中命名的公式的?

    1 回复  |  直到 10 年前
        1
  •  9
  •   vrajs5    10 年前

    这相当棘手:

    m <- match.call(expand.dots = FALSE)
    # ...
    m[[1L]] <- as.name("model.frame")
    m <- eval(m, parent.frame())
    

    函数使用 match.call 若要了解如何调用,请修改调用以将被调用函数替换为 model.frame ,并通过 eval 使用接收到的参数(尽管第一部分被替换为 # ... 删除几个参数),以及 模型框架 使用 formula 参数。参见以下文件: 打电话 , 埃瓦 模型框架 尝试一下,例如,试着理解这里发生了什么:

    f <- function(formula, data) { 
      m <- match.call()
      m[[1L]] <- as.name('model.frame')
      eval(m, parent.frame())
    }
    f(x ~ y)
    Error in eval(expr, envir, enclos) : object 'x' not found
    x <- c(1,2,3)
    f(x ~ y)
    Error in eval(expr, envir, enclos) : object 'y' not found
    y <- c(3,4,5)
    f(x ~ y)
      x y
    1 1 3
    2 2 4
    3 3 5
    d <- as.data.frame(matrix(c(1,2,3,4),nrow=2))
    names(d) <- c('foo', 'bar')
    f(foo ~ bar, d)
      foo bar
    1   1   3
    2   2   4