2013-06-30 20 views
7

Voglio creare una funzione wrapper che sostituisca alcuni degli argomenti predefiniti.R: utilizzo dell'argomento ellissi (...)

Ecco il cuore del problema che sto lottando con:

Error in localWindow(xlim, ylim, log, asp, ...) : 
    formal argument "cex" matched by multiple actual arguments 

Ora un po 'di contesto. Supponiamo che io definisco una funzione wrapper per il grafico come questo:

myplot <- function(x, ...) { 
    plot(x, cex= 1.5, ...) 
} 

Se chiamo myplot(1:10, cex= 2) mi metterò l'errore precedente. So che posso girare ... a un elenco

l <- list(...) 

e poi ho potuto fare

if(is.null(l[["cex"]])) l[["cex"]] <- 2 

Tuttavia, come posso "insert" questa lista tornare all'argomento puntini di sospensione? Qualcosa di simile (so che questo non funziona):

... <- l 

EDIT: ho potuto utilizzare le impostazioni predefinite in myplot definizione (come suggerito nella risposta da @Thomas), ma io non voglio: la funzione di interfaccia diventerà disordinato. Credo che avrei potuto definire una funzione di supporto del genere:

.myfunchelper <- function(x, cex= 2.0, ...) { 
    plot(x, cex= cex, ...) 
} 

myfunc <- function(x, ...) { 
    .myfunchelper(x, ...) 
} 

Ma (i) è meno elegante e (ii) non soddisfa la mia curiosità.

risposta

11

UNA RISPOSTA REALE:

È possibile farlo attraverso un po 'di inganno. Innanzitutto, definisci la tua funzione come prima, ma includi una lista con gli argomenti predefiniti all'interno della funzione. Quindi è possibile analizzare qualsiasi argomento entrare attraverso ... come un elenco, sostituire i valori predefiniti con qualsiasi cosa in ... e quindi passare l'elenco aggiornato di argomenti tramite do.call.

myplot <- function(x, ...) { 
    args1 <- list(cex=4, main="Default Title") # specify defaults here 
    inargs <- list(...) 
    args1[names(inargs)] <- inargs 
    do.call(plot, c(list(x=x), args1)) 
} 

myplot(x=1:3) # call with default arguments 
myplot(x=1:3, cex=2, main="Replacement", xlab="Test xlab") # call with optional arguments 

COMMENTO PRECEDENTI:

Il problema qui può essere visto attraverso un paio di funzioni di esempio:

myplot1 <- function(x, ...) { 
    plot(x, cex= 1.5, ...) 
} 

myplot2 <- function(x, cex=3, ...) { 
    plot(x, cex=cex, ...) 
} 

myplot3 <- function(x, ...) { 
    plot(x, ...) 
} 

myplot1(1:3, cex=3) # spits your error 
myplot2(1:3, cex=3) # works fine 
myplot3(1:3, cex=3) # works fine 

In myplot2, si specifica un valore predefinito di cex ma può cambiarlo. In myplot3, cex viene semplicemente passato. Se si esegue myplot2 con due cex argomenti, vedrete che cosa sta accadendo con la funzione (myplot1):

myplot2(1:3, cex=3, cex=1.5) # same error as above 

Quindi, siete probabilmente meglio evitare di impostare eventuali inadempienze in plot(), così poi si può passare nulla attraverso lo ... in myplot.

+0

Sì, ma questo è esattamente ciò che voglio evitare. Il vero problema è complesso, e non voglio mettere i valori predefiniti nella definizione della chiamata di funzione - ci sono già troppi argomenti. – January

+0

Ho aggiornato in base alle risposte da: http://stackoverflow.com/questions/7028385/can-i-remove-an-element-in-dot-dot-dot-and-pass-it-on/7028786# 7028786 – Thomas

Problemi correlati