2009-04-21 12 views
7

Ho cercato di saperne di più su R (e sulla scrittura di estensioni C) e ho pensato che potesse essere d'aiuto leggere il codice sorgente di alcuni pacchetti ben noti. Ho deciso di iniziare con rpart che è definito come:Come si può utilizzare un parametro funzione senza menzionarlo nel corpo della funzione?

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

Ho fatto una rapida ricerca attraverso la fonte e non vedo formula menzionata in qualsiasi parte del corpo della funzione ma so che in qualche modo rpart sta usando quel parametro. Com'è che rpart sta usando la formula senza che il suo nome sia nel corpo della funzione?

risposta

9

E 'piuttosto difficile:

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

La funzione utilizza match.call per scoprire come viene chiamato, modifica la chiamata per sostituire la funzione chiamata da model.frame, e chiede via eval con i parametri che ha ricevuto (sebbene la parte sostituita da # ... rimuova molti parametri) e model.frame utilizza il parametro formula. Consulta la documentazione di match.call, eval e model.frame e prova un po ', ad es. prova a capire cosa sta succedendo qui:

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 
Problemi correlati