2009-04-21 4 views
7

Ich habe versucht, mehr über R zu erfahren (und C-Erweiterungen zu schreiben) und ich dachte, es könnte helfen, die Quelle für einige bekannte Pakete zu lesen. Ich beschloss, mit rpart zu beginnen, die definiert ist als:Wie kann ein Funktionsparameter verwendet werden, ohne ihn im Funktionskörper zu erwähnen?

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

ich eine schnelle Suche durch die Quelle tat und ich sehe nicht, Formel überall in dem Funktionskörper erwähnt noch weiß ich, dass irgendwie rpart diese Parameter verwendet. Wie kommt es, dass rpart eine Formel verwendet, ohne dass ihr Name im Funktionskörper enthalten ist?

Antwort

9

Es ist ziemlich heikel:

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

Die Funktion match.call verwendet, um herauszufinden, wie es genannt wird, ändert den Aufruf an die genannte Funktion von model.frame zu ersetzen, und ruft sie über eval mit den Parametern, die er empfangen (obwohl der Teil, den ich durch # ... ersetzt habe, einige der Parameter entfernt, und model.frame den Parameter formula verwendet. Siehe die Dokumentation von match.call, eval und und experimentiere ein wenig, z.B. versuchen Sie zu verstehen, was hier passiert:

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 
Verwandte Themen