2009-04-21 73 views
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如何使用公式名称不在函数体内?

回答

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,evalmodel.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 
相关问题