La valutazione non standard è molto utile quando utilizza i verbi di dplyr. Ma può essere problematico quando si usano quei verbi con argomenti di funzione. Per esempio diciamo che voglio creare una funzione che mi dà il numero di righe per una determinata specie.Creare una funzione con un argomento passato a dplyr :: filter qual è il modo migliore per aggirare nse?
# 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
Esempio non funzionante
Questa funzione non funziona come previsto perché species
viene interpretata nel contesto del frame di dati dell'iride anziché essere interpretato nel contesto dell'argomento funzione:
nrowspecies0 <- function(dtf, species){
dtf %>%
filter(species == species) %>%
nrow()
}
nrowspecies0(iris, species = "versicolor")
# [1] 150
3 esempi di attuazione
Per aggirare la valutazione non standard, io di solito aggiungere l'argomento con una sottolineatura:
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
non è del tutto soddisfacente in quanto cambia il nome dell'argomento funzione per qualcosa di meno user friendly. Oppure si basa sul completamento automatico che temo non sia una buona pratica per la programmazione. Per mantenere un bel nome dell'argomento, che potevo fare:
nrowspecies2 <- function(dtf, species){
species_ <- species
dtf %>%
filter(species == species_) %>%
nrow()
}
nrowspecies2(iris, species = "versicolor")
# [1] 50
Un altro modo per aggirare la valutazione non standard sulla base di this answer. interp()
interpreta species
nel contesto dell'ambiente funzione:
nrowspecies3 <- function(dtf, species){
dtf %>%
filter_(interp(~species == with_species,
with_species = species)) %>%
nrow()
}
nrowspecies3(iris, species = "versicolor")
# [1] 50
Considerando la funzione 3 di cui sopra, qual è il preferito - più robusta - modo per implementare questa funzione di filtro? Ci sono altri modi?
Grazie, l'e-mail da Hadley lei ha citato mi ha fatto guardare 'vignetta (" lazyeval ")" che spiega che "Ogni funzione che utilizza NSE dovrebbe avere una finestra di escape standard di valutazione (SE) che esegue il calcolo effettivo. Il nome della funzione SE dovrebbe terminare con _." Vorrei una spiegazione di ciò che Hadley intende con "adatto per programmare con" alla fine della vignetta 'lazyeval'. Questo implica che non dovrei usare nse all'interno delle funzioni? –
Sì, o almeno dovresti evitarlo quando possibile. Consulta anche la sezione "Aspetti negativi della valutazione non standard" qui http://adv-r.had.co.nz/Computing-on-the-language.html Il problema di base, come Hadley spiega in quel capitolo, è che l'NSE è molto difficile da ragionare all'interno di un programma perché le funzioni possono essere diverse in diversi contesti_. Cioè, se utilizzato in modo interattivo, una funzione NSE può agire in modo diverso rispetto a quando viene utilizzata in una funzione. – jaimedash
Hadley spiega il concetto di "trasparenza referenziale" in [il suo keynote alla conferenza UseR del 2016] (https://channel9.msdn.com/Events/useR-international-R-User-conference/useR2016/Towards-a-grammar -di-grafica interattiva) (a 38min30s)."La formula mantiene sia il codice che l'ambiente in cui questo codice deve essere valutato, senza effettivamente fare la valutazione." Ho creato un esempio utilizzando una formula e incollato in una nuova risposta. –