2009-04-21 18 views
7

He intentado aprender más sobre R (y escribir extensiones C) y pensé que podría ser útil leer la fuente de algunos paquetes conocidos. Decidí comenzar con rpart que se define como:¿Cómo se puede usar un parámetro de función sin mencionarlo en el cuerpo de la función?

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

Hice una búsqueda rápida a través de la fuente y no veo fórmula mencionado en cualquier parte del cuerpo de la función sin embargo, sé que de alguna manera rpart está utilizando ese parámetro. ¿Cómo es que rpart usa fórmula sin que su nombre esté en el cuerpo de la función?

Respuesta

9

es bastante complicado:

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

La función utiliza match.call para averiguar cómo está siendo llamado, modifica la propuesta para sustituir la función llamada por model.frame, y lo llama a través de eval con los parámetros que recibió (aunque la parte que reemplacé por # ... elimina varios de los parámetros) y model.frame usa el parámetro formula. Consulte la documentación de match.call, eval y model.frame, y experimente un poco, p. Ej. Trate de entender lo que está sucediendo aquí:

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 
Cuestiones relacionadas