2015-12-08 16 views
9

Ich versuche, die Punkte (...) innerhalb einer benutzerdefinierten Funktion zu ändern. Hier ist ein vereinfachtes Beispiel für meine plot2-Funktion, die eine grafische Darstellung zeigt den Bildschirm mit type="p" (Standardeinstellung) und speichert eine svg mit type="l". Das Problem tritt auf, wenn eine der ... Plot-Optionen bereits in der Funktion ist. In diesem Beispiel wird "type" mit mehreren tatsächlichen Argumenten verglichen.Ändern Punkte (...) in einer Funktion

plot2 <-function(...){ 
plot(...) #visible on screen 

svg("c:/temp/out.svg") #saved to file 
plot(...,type="l") 
dev.off() 
} 

#This works 
plot2(1:10) 
#This does not work because type is redefined 
plot2(1:10, type="o") 

Ich habe versucht, die Punkte in einem list innerhalb der Funktion zu setzen und ändern, aber plot keine Liste als Eingabe akzeptieren.

#Does not work 
plot2 <-function(...){ 
plot(...) 

dots <<-list(...) 
print(dots) 
if("type" %in% names(dots)) dots$type="l" 
print(dots) 

svg("c:/temp/out.svg") 
plot(dots) 
dev.off() 
} 
plot2(1:10, type="o") 
Error in xy.coords(x, y, xlabel, ylabel, log) : 
    'x' is a list, but does not have components 'x' and 'y' 

Antwort

12

In Fällen, in denen Sie eine modifizierte Version von ... weiterleiten möchten, müssen Sie zwei Dinge tun:

  1. Capture- die Punkte
  2. Vorwärts die gefangenen Punkte über do.call.

Dies funktioniert wie folgt:

plot2 = function (...) { 
    # capture: 
    dots = list(...) 

    # modify: 
    dots$type = 'l' 

    # forward call: 
    do.call(plot, dots) 
} 

Im Allgemeinen do.call(f, list(‹…›)) entspricht f(‹…›).

+0

Vielen Dank. Einfach und effektiv. –

1

Für das, was Sie wollen, gibt es eine einfachere (und besser) Art und Weise, und Sie brauchen nicht zu ... berühren. Durch die explizite Argumente definieren, die eine spezielle Behandlung benötigen, nehmen Sie sie aus dem Fang alle .... Dies ist auch ein vernünftiger Ansatz, der genauer beschreibt, was die Funktion macht (in ihren formalen Argumenten). Hier ist, wie es geht:

plot2 <- function(x, type = "p", ...) { 
    plot(x, type = type, ...) #visible on screen 

    svg("out.svg") #saved to file 
    plot(x, ..., type = "l") 
    dev.off() 
} 

plot2(1:10) 
plot2(1:10, type = "o") 
+0

Das von mir bereitgestellte Beispiel ist vereinfacht und Ihre Lösung wäre mit meinen tatsächlichen Funktionen nicht optimal. In meinem realen Beispiel ist die "Plot" -Funktion eine benutzerdefinierte Plot-Funktion mit fast 50 Argumenten. Die Funktion 'plot2' ist nur ein Wrapper, um das Diagramm anzuzeigen und in verschiedenen Formaten zu speichern. –

+0

Sorry, aber trotzdem funktioniert es. Es sind nicht alle Argumente, die an ... übergeben werden können, sondern nur die wenigen Argumente, die Sie auf besondere Weise in Ihrer Funktion manipulieren, die explizit aus ... entfernt werden müssen. –

Verwandte Themen