我一直在努力学习更多关于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如何使用公式而其名称不在函数体中?
答案 0 :(得分: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