Criando uma função com um argumento passado para dplyr :: filter, qual é a melhor maneira de solucionar o nse?

A avaliação não padronizada é realmente útil ao usar os verbos do dplyr. Mas pode ser problemático ao usar esses verbos com argumentos de função. Por exemplo, digamos que eu quero criar uma função que me dê o número de linhas para uma determinada espécie.

# 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
Exemplo não está funcionando

Esta função não funciona como esperado porquespecies é interpretado no contexto do quadro de dados da íris em vez de ser interpretado no contexto do argumento da função:

nrowspecies0 <- function(dtf, species){
    dtf %>%
        filter(species == species) %>%
        nrow()
}
nrowspecies0(iris, species = "versicolor")
# [1] 150
3 exemplos de implementação

Para contornar a avaliação não padrão, costumo acrescentar o argumento com um sublinhado:

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

Não é completamente satisfatório, pois altera o nome do argumento da função para algo menos amigável. Ou depende do preenchimento automático, o que, receio, não é uma boa prática para programação. Para manter um bom nome de argumento, eu poderia fazer:

nrowspecies2 <- function(dtf, species){
    species_ <- species
    dtf %>%
        filter(species == species_) %>%
        nrow()
}
nrowspecies2(iris, species = "versicolor")
# [1] 50

Outra maneira de contornar a avaliação não padrão com base emesta resposta. interp() interpretaspecies no contexto do ambiente de funções:

nrowspecies3 <- function(dtf, species){
    dtf %>%
        filter_(interp(~species == with_species, 
                       with_species = species)) %>%
        nrow()
}
nrowspecies3(iris, species = "versicolor")
# [1] 50

Considerando a função 3 acima, qual é a maneira preferida - mais robusta - de implementar essa função de filtro? Existem outras maneiras?

questionAnswers(3)

yourAnswerToTheQuestion