Nicht-Standard-Auswertung ist wirklich praktisch, wenn dplyrs Verben verwendet. Aber es kann problematisch sein, wenn diese Verben mit Funktionsargumenten verwendet werden. Zum Beispiel lassen Sie uns sagen, dass ich eine Funktion erstellen möchte, die gibt mir die Anzahl der Zeilen für eine bestimmte Spezies.Erstellen einer Funktion mit einem Argument, das an dplyr :: filter übergeben wird, was ist der beste Weg, um nse zu umgehen?
# Load packages and prepare data
library(dplyr)
library(lazyeval)
# I prefer lowercase column names
names(iris) <- tolower(names(iris))
# Number of rows for all species
nrow(iris)
# [1] 150
Beispiel nicht funktionierend
dieser Funktion als nicht funktioniert, weil erwartet species
im Rahmen des Irisdatenrahmen interpretiert statt im Rahmen der Funktionsargument interpretiert wird:
nrowspecies0 <- function(dtf, species){
dtf %>%
filter(species == species) %>%
nrow()
}
nrowspecies0(iris, species = "versicolor")
# [1] 150
3 Beispiele für die Umsetzung
Um Nicht-Standard-Auswertung zu arbeiten, ich in der Regel das Argument mit einem Unterstrich anhängen:
nrowspecies1 <- function(dtf, species_){
dtf %>%
filter(species == species_) %>%
nrow()
}
nrowspecies1(iris, species_ = "versicolor")
# [1] 50
# Because of function name completion the argument
# species works too
nrowspecies1(iris, species = "versicolor")
# [1] 50
Es ist nicht völlig zufrieden stellend ist , da sie den Namen des Funktionsargument zu etwas weniger benutzerfreundlich ändert. Oder es beruht auf Autovervollständigung , die ich befürchte, ist keine gute Praxis für die Programmierung. Um ein schönes Argument Namen zu behalten, ich tun konnte:
nrowspecies2 <- function(dtf, species){
species_ <- species
dtf %>%
filter(species == species_) %>%
nrow()
}
nrowspecies2(iris, species = "versicolor")
# [1] 50
Eine andere Möglichkeit, um Nicht-Standard-Auswertung auf this answer Basis zu arbeiten. interp()
interpretiert species
im Rahmen der Funktion Umgebung:
nrowspecies3 <- function(dtf, species){
dtf %>%
filter_(interp(~species == with_species,
with_species = species)) %>%
nrow()
}
nrowspecies3(iris, species = "versicolor")
# [1] 50
Betrachtet man die 3-Funktion oben, was ist der bevorzugte - robusteste - Weg, um diese Filterfunktion zu implementieren? Gibt es noch andere Möglichkeiten?
Danke, die E-Mail von Hadley Sie erwähnt mir 'Vignette aussehen (“ lazyeval ")' was erklärt, dass "Jede Funktion, die NSE verwendet, sollte eine Standardauswertungs (SE) Escape-Schraffur haben, die die eigentliche Berechnung ausführt. Der SE-Funktionsname sollte mit _ enden." Ich möchte eine Erklärung dessen haben, was Hadley am Ende der "Lazyeval" -Vignette mit "geeignet zum Programmieren" meint. Bedeutet das, dass ich nse Inside Funktionen nicht benutzen sollte? –
Ja, oder zumindest sollten Sie es vermeiden, wenn möglich. Siehe auch Abschnitt "Nachteile der Nicht-Standard-Bewertung" hier http://adv-r.had.co.nz/Computing-on-the-language.html Das grundlegende Problem, wie Hadley in diesem Kapitel erklärt, ist NSE ist Es ist sehr schwierig, innerhalb eines Programms nachzudenken, weil Funktionen in verschiedenen Kontexten anders funktionieren können. Das heißt, wenn sie interaktiv verwendet werden, kann eine NSE-Funktion anders als bei einer Verwendung in einer Funktion wirken. – jaimedash
Hadley erklärt das Konzept der "referenziellen Transparenz" in [seiner Keynote auf der UseR-Konferenz 2016] (https://channel9.msdn.com/Events/useR-international-R-User-conference/useR2016/Towards-a-grammar -von-interaktiven-Grafiken) (bei 38min30s)."Formel halten Sie sowohl den Code als auch die Umgebung, in der dieser Code ausgewertet werden soll, ohne tatsächlich die Auswertung durchzuführen." Ich habe ein Beispiel mit einer Formel erstellt und in eine neue Antwort eingefügt. –