2017-10-05 2 views
0

Ich versuche herauszufinden, wie man eine Funktion erstellt, die eine Menge benannter Argumente mit Argumentwerten aus einer bestimmten Liste aufnimmt und ändern Sie die Liste, indem Sie die Elemente (in den Elementnamen der Liste, aber die Elementwerte der Funktionsargumente) durch die Argumentnamen der Funktionsargumente ersetzen. (Dieser Vektor von Namen wird zuerst von einem Datenrahmen genommen, obwohl ich denke, dass das nicht wichtig ist und es unten nicht eingeschlossen hat). Argumente, die zu mehr als einem Namen ausgewertet werden oder die Bereiche über numerische oder logische Vektoren darstellen, werden zur späteren Verarbeitung separat in Form von Anführungszeichen gespeichert.R: Wie kann ich mit benannten Argumenten die Namen einer Liste von benannten Objekten abgleichen und bearbeiten

Das scheint wie ein einfaches Problem, aber ich konnte nicht herausfinden, wie es geht. Die entscheidende Sache ist, dass es vollständig programmgesteuert erfolgen muss. Meine wirkliche Funktion wird eine unsichere und potentiell große Anzahl von Argumenten haben, wie unten beschrieben.

Um zu zeigen, was ich rede, hier ist ein Beispiel „Rahmen“ Funktion, den Mut fehlt, die tatsächlich die Veränderungen machen würde:

für die
ChangeIt <- function(dog = NULL, cat = NULL, cow = NULL, ...){ 
xx <- c("a", "b", "c", "d", "e", "f", "g", "h") 
# missing stuff here 
if (is.NULL(cow)) print("No cows!") 
list(xx, complex_assignments = list()) 
} 

Hier ist eine Reihe von möglichen Werten für benannte Argumente Funktion oben.

ChangeIt(dog = "b", cat = "a", yak = "f", eel = "g", zoo = 3:5) 

Und das ist, was ChangeIt basierend auf diesen Werten zurückgeben sollte. (Dies ist eine Beschreibung, nicht, wie es buchstäblich drucken würde)

"No cows!" (als Nebeneffekt gedruckt).

dann zurück:

list(xx = c("cat", "dog", "c", "d", "e", "yak", "eel", "h"), 
complex_assignments = list("zoo = 3:5")) 

Sie sehen, dass die Werte der genannten Argumente werden verwendet, um die Elemente in der ursprünglichen Liste übereinstimmen, während der Name von diesem Argument umgewandelt wird in Text und dann das identifizierte Element ersetzt . Das ist das Ziel.

Nur um meinen Zweck zu erklären, möchte ich zwei getrennte Sätze von Namen für einen Datenrahmen pflegen, einen für das Gesicht, das die Welt zeigt, und einen zweiten Satz nur für die Methoden, die ich für dieses Objekt schreibe.

Antwort

1

Wie dies über

ChangeIt <- function(dog = NULL, cat = NULL, cow = NULL, ...){ 
    cc <- match.call() 
    cc[[1]] <- quote(list) 
    allargs <- eval(cc) 
    xx <- c("a", "b", "c", "d", "e", "f", "g", "h") 
    toreplace <- sapply(allargs, function(x) {length(x)==1 && x %in% xx}) 
    xx <- replace(xx, match(unlist(allargs[toreplace]), xx), names(allargs[toreplace])) 
    if (is.null(cow)) print("No cows!") 
    list(xx=xx, complex_assignments = allargs[!toreplace]) 
} 

ChangeIt(dog = "b", cat = "a", yak = "f", eel = "g", zoo = 3:5) 

Hier verwenden wir match.call() alle Funktionsaufrufe greifen und es zu list() abgehen eine Liste aller Werte zu generieren. Dann können wir das wie eine normale Liste zu den Transformationen verwenden, an denen Sie interessiert sind.

+0

Danke MrFlick! Das macht es für mich. Ich bin eigentlich ziemlich begeistert davon - es ermöglicht meine einfältige Herangehensweise an die S3-Klassenkonstruktion. Jetzt brauche ich nur noch, um herauszufinden, ob es sinnvoller ist, den oben konstruierten Vektor als Attribut des DF oder in einer neuen Spalte (oder auf andere Weise) zu speichern. – andrewH

Verwandte Themen