非標準評価は、dplyr の動詞を使用する場合に非常に便利です。しかし、関数の引数でこれらの動詞を使用すると問題が発生する可能性があります。たとえば、特定の種の行数を取得する関数を作成したいとします。
# 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
例が機能しない
species
この関数は、関数の引数のコンテキストではなく、アイリス データ フレームのコンテキストで解釈されるため、期待どおりに動作しません。
nrowspecies0 <- function(dtf, species){
dtf %>%
filter(species == species) %>%
nrow()
}
nrowspecies0(iris, species = "versicolor")
# [1] 150
3つの実装例
非標準の評価を回避するために、通常は引数にアンダースコアを追加します。
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
関数の引数の名前を使いにくい名前に変更するため、完全に満足できるものではありません。または、オートコンプリートに依存していますが、これはプログラミングの良い習慣ではありません。素敵な引数名を保持するには、次のようにします。
nrowspecies2 <- function(dtf, species){
species_ <- species
dtf %>%
filter(species == species_) %>%
nrow()
}
nrowspecies2(iris, species = "versicolor")
# [1] 50
この回答に基づいて非標準評価を回避する別の方法。
関数環境のコンテキストでinterp()
解釈します。species
nrowspecies3 <- function(dtf, species){
dtf %>%
filter_(interp(~species == with_species,
with_species = species)) %>%
nrow()
}
nrowspecies3(iris, species = "versicolor")
# [1] 50
上記の 3 つの関数を考慮して、このフィルター関数を実装するための推奨される (最も堅牢な) 方法は何ですか? 他の方法はありますか?