Creating a function with an argument passed to dplyr::filter what is the best way to work around nse?

后端 未结 3 935
陌清茗
陌清茗 2020-12-30 10:13

Non standard evaluation is really handy when using dplyr\'s verbs. But it can be problematic when using those verbs with function arguments. For example let us say that I

3条回答
  •  被撕碎了的回忆
    2020-12-30 10:49

    The answer from @eddi is correct about what's going on here. I'm writing another answer that addresses the larger request of how to write functions using dplyr verbs. You'll note that, ultimately, it uses something like nrowspecies2 to avoid the species == species tautology.

    To write a function wrapping dplyr verb(s) that will work with NSE, write two functions:

    First write a version that requires quoted inputs, using lazyeval and an SE version of the dplyr verb. So in this case, filter_.

    nrowspecies_robust_ <- function(data, species){ 
      species_ <- lazyeval::as.lazy(species) 
      condition <- ~ species == species_ # *
      tmp <- dplyr::filter_(data, condition) # **
      nrow(tmp)
    } 
    nrowspecies_robust_(iris, ~versicolor) 
    

    Second make a version that uses NSE:

    nrowspecies_robust <- function(data, species) { 
      species <- lazyeval::lazy(species) 
      nrowspecies_robust_(data, species) 
    } 
    nrowspecies_robust(iris, versicolor) 
    

    * = if you want to do something more complex, you may need to use lazyeval::interp here as in the tips linked below

    ** = also, if you need to change output names, see the .dots argument

    • For the above, I followed some tips from Hadley

    • Another good resource is the dplyr vignette on NSE, which illustrates .dots, interp, and other functions from the lazyeval package

    • For even more details on lazyeval see it's vignette

    • For a thorough discussion of the base R tools for working with NSE (many of which lazyeval helps you avoid), see the chapter on NSE in Advanced R

提交回复
热议问题