Erstellen einer Funktion mit einem an dplyr :: filter übergebenen Argument Was ist der beste Weg, um nse zu umgehen?

8

Nicht standardmäßige Auswertung ist wirklich praktisch, wenn mit dplyrs Verben. Aber es kann problematisch sein, wenn Sie diese verwenden Verben mit Funktionsargumenten. Lassen Sie uns zum Beispiel sagen, dass ich eine Funktion erstellen möchte, die gibt mir die Anzahl der Reihen für eine bestimmte Spezies.

%Vor%

Beispiel funktioniert nicht

Diese Funktion funktioniert nicht wie erwartet, da species wird im Kontext des Iris-Datenrahmens interpretiert anstatt im Kontext der Funktionsargument:

%Vor%

3 Beispiele für die Implementierung

Um eine nicht standardisierte Auswertung zu umgehen, Normalerweise füge ich das Argument mit einem Unterstrich an:

%Vor%

Es ist nicht vollständig zufriedenstellend da es den Namen des Funktionsarguments ändert etwas weniger benutzerfreundlich. Oder es beruht auf Autovervollständigung was ich fürchte, ist keine gute Übung zum Programmieren. Um einen netten Argumentnamen zu behalten, Ich könnte tun:

%Vor%

Eine weitere Möglichkeit, um eine nicht standardisierte Auswertung zu umgehen basierend auf dieser Antwort . interp() interpretiert species im Kontext der Funktionsumgebung:

%Vor%

Betrachtet man die obige 3 Funktion, Was ist die bevorzugte - robusteste - Art, diese Filterfunktion zu implementieren? Gibt es andere Möglichkeiten?

    
Paul Rougieux 15.04.2016, 12:42
quelle

3 Antworten

5

Die Antwort von @eddi ist richtig, was hier vor sich geht. Ich schreibe eine andere Antwort, die die größere Anforderung an das Schreiben von Funktionen mit dplyr Verben adressiert. Sie werden feststellen, dass es letztlich so etwas wie nrowspecies2 verwendet, um die species == species tautology zu vermeiden.

Um schreiben Sie eine Funktion Wrapping dplyr Verb (n), die mit NSE funktionieren wird, schreiben Sie zwei Funktionen:

Zuerst schreiben Sie eine Version, die in Anführungszeichen eingeschlossene Eingaben benötigt, mit lazyeval und eine SE-Version des Verbs dplyr . Also in diesem Fall filter_ .

%Vor%

Zweite macht eine Version, die NSE verwendet:

%Vor%

* = Wenn Sie etwas Komplexeres tun möchten, müssen Sie möglicherweise lazyeval::interp hier verwenden, wie in den unten verlinkten Tipps

** = Wenn Sie die Namen der Ausgaben ändern müssen, lesen Sie auch das Argument .dots

jaimedash 15.04.2016 18:30
quelle
3

Diese Frage hat absolut nichts mit einer nicht standardisierten Bewertung zu tun. Lassen Sie mich Ihre ursprüngliche Funktion umschreiben, um das klar zu machen:

%Vor%

Der Ausdruck innerhalb Ihres filter wird immer als TRUE ausgewertet (fast immer - siehe Beispiel unten), deshalb funktioniert es nicht, nicht wegen einiger NSE-Magie.

Dein nrowspecies2 ist der Weg zu gehen.

Fwiw, species in Ihrer nrowspecies0 wird zwar als Spalte ausgewertet, nicht als Eingabevariable species , und Sie können dies überprüfen, indem Sie nrowspecies0(iris, NA) mit nrowspecies4(iris, NA) vergleichen.

    
eddi 15.04.2016 15:26
quelle
0

in seinem 2016 UseR Talk (@ 38min30s) erklärt Hadley Wickham das Konzept der referenziellen Transparenz . Mit einer Formel kann die Filterfunktion wie folgt umformuliert werden:

%Vor%

Dies hat den zusätzlichen Vorteil, generischer zu sein

%Vor%     
Paul Rougieux 11.08.2016 13:56
quelle

Tags und Links