2009-04-21 24 views
7

Próbowałem dowiedzieć się więcej o R (i pisaniu rozszerzeń C) i pomyślałem, że może to pomóc w odczytaniu źródła dla niektórych dobrze znanych pakietów. Postanowiłem zacząć rpart który jest zdefiniowany jako:W jaki sposób można użyć parametru funkcji bez wspominania o nim w treści funkcji?

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

Zrobiłem szybkie wyszukiwanie przez źródło i nie widzę formuła wymienione w dowolnym miejscu na ciele funkcji jeszcze wiem, że jakoś rpart jest za pomocą tego parametru. Jak to jest, że rpart używa formuły bez jej nazwy w ciele funkcji?

Odpowiedz

9

To dość trudne:

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

Funkcja wykorzystuje match.call aby dowiedzieć się, w jaki sposób jest on nazywany, modyfikuje wezwanie do zastąpienia zwaną funkcję model.frame i wzywa go poprzez eval z parametrami to odebranych (chociaż część I zastąpiona przez # ... usuwa kilka parametrów), a model.frame używa parametru formula. Zobacz dokumentację match.call, eval i model.frame i trochę poeksperymentuj, np. spróbuj zrozumieć, co się tutaj dzieje:

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 
Powiązane problemy