7

我一直在尝试更多地了解 R(和编写 C 扩展),我认为阅读一些知名包的源代码可能会有所帮助。我决定从 rpart 开始,它被定义为:

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

我对源代码进行了快速搜索,但我没有看到函数体中任何地方提到的公式,但我知道 rpart 以某种方式使用了该参数。rpart 是如何使用公式而其名称不在函数体中的?

4

1 回答 1

9

这很棘手:

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

该函数用于match.call找出它是如何被调用的,修改调用以替换被调用函数model.frame,并eval使用它接收到的参数调用它(尽管我替换的部分# ...删除了几个参数),并model.frame使用formula参数。match.call请参阅、eval和的文档model.frame并进行一些实验,例如尝试了解此处发生的情况:

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
于 2009-04-22T09:32:47.140 回答