2011-03-06 19 views
5

Tengo una pregunta sobre el alcance de los argumentos dot-dot-dot. Considere el siguiente function`foo =Alcance de los argumentos punto-dot-dot

foo <- function(x, ...){ 
    require(classInt); 
    intvl = classIntervals(x, ...); 
    return(intvl); 
} 

La función funciona muy bien para las siguientes llamadas

x = runif(100, 0, 100); 
y1 = foo(x, n = 5, style = 'quantile'); 
y2 = foo(x, style = 'equal'); 

Pero cuando trato de utilizar el estilo = argumento 'fijo', que necesita un argumento así fixedBreaks , consigo

y3 = foo(x, style = 'fixed', fixedBreaks = seq(0, 100, 20)) 

error en eval (expr, AMBIENTALIZ, enclos): El ... la lista no contiene 2 elementos

cuenta que la siguiente aplicación funciona perfectamente

y5 = classIntervals(x, style = 'fixed', fixedBreaks = seq(0, 100, 20)) 

I suspsect que esto tiene algo que ver con reglas de alcance, pero han sido incapaces de poner mi dedo en la llaga. Cualquier ayuda sobre esto sería muy apreciada.

EDITAR. Arreglé un truco más simple que lo hace funcionar. Creo que es un problema match.call, ya que existe el mismo problema para style = 'pretty'. Una mirada rápida al código muestra que estos son los dos estilos para los que se realizan tales match.calls, por lo que es muy probable que esta sea la fuente de error. Cualquier caso, aquí está mi propuesta truco

foo2 <- function(x, ...){ 
    require(classInt); 
    y = list(...); y$var = x; 
    intvl = do.call('classIntervals', y); 
} 

y6 = foo2(x, style = 'fixed', fixedBreaks = seq(0, 100, 20)) 

Creo que la respuesta de Richie a mi pregunta arroja algo de luz sobre por qué mi código anterior no funcionó. Pero, todavía no entiendo por qué lo hace.

+1

Parece un error en 'classIntervals' para mí. El autor está tratando de ser elegante con 'match.call' – hadley

+0

Hmmm. Debería enviar un correo electrónico al autor del paquete y ver lo que él/ella podría tener que decir. Gracias por la pista – Ramnath

Respuesta

2

Dentro de la función foo, la elipsis contiene 2 elementos. Llame a esta modificación para ver esto.

foo <- function(x, ...){ 
    require(classInt); 
    print(list(...)) 
    intvl = classIntervals(x, ...); 
    return(intvl); 
} 

Una vez classIntervals se llama, los cambios suspensivos, ya que los argumentos se hacen coincidir de manera diferente. Aquí está la firma de esa función

classIntervals(var, n, style = "quantile", rtimes = 3, ..., 
    intervalClosure = "left", dataPrecision = NULL) 

En su llamada que falla, usted tiene tres argumentos

foo(x, style = 'fixed', fixedBreaks = seq(0, 100, 20)) 

x consigue emparejados hasta var través concordancia posicional (es decir, porque está en la primera posición en el firma en cada caso).

style se empareja hasta style, a través de la coincidencia de nombres (porque tienen el mismo nombre, duh).

fixedBreaks no puede coincidir con la posición o el nombre por lo que termina en los puntos.

Por lo tanto, la elipsis contiene 1 argumento, y el error "La ... lista no contiene 2 elementos" es correcto (aunque bastante tonto).


EDITAR: Se sugiere solución a classIntervals.Si usted está en contacto el autor, a continuación, sugieren la sustitución de las líneas 42-43

mc <- match.call(expand.dots = FALSE) 
fixedBreaks <- sort(eval(mc$...$fixedBreaks)) 

con

fixedBreaks <- list(...)$fixedBreaks 

Ésta es (creo) lo que significaban, y seemes para resolver el mensaje de error tonto.

+0

Interesante. ¡Necesito trabajar en esto para asimilar lo que se dice! – Ramnath