非標準の評価を維持する方法でdplyrをリファクタリングする際に問題が発生しています。常に選択して名前を変更する関数を作成したいとします。dplyrとlazyevalを使用したプログラミング
library(lazyeval)
library(dplyr)
df <- data.frame(a = c(1,2,3), f = c(4,5,6), lm = c(7, 8 , 9))
select_happy<- function(df, col){
col <- lazy(col)
fo <- interp(~x, x=col)
select_(df, happy=fo)
}
f <- function(){
print('foo')
}
select_happy()
この記事Refactor R code when library functions use non-standard evaluationへの答えに応じて書かれています。 select_happy()
は、未定義またはグローバル環境で定義されている列名で機能します。ただし、列名が別の名前空間内の関数の名前でもある場合は、問題になります。 FとLMのlazy()
を呼び出す
select_happy(df, a)
# happy
# 1 1
# 2 2
# 3 3
select_happy(df, f)
# happy
# 1 4
# 2 5
# 3 6
select_happy(df, lm)
# Error in eval(expr, envir, enclos) (from #4) : object 'datafile' not found
environment(f)
# <environment: R_GlobalEnv>
environment(lm)
# <environment: namespace:stats>
は、LMのための関数定義は怠惰なオブジェクトに表示されている怠惰なオブジェクトの差を示しており、Fのためには、関数の名前だけです。
lazy(f)
# <lazy>
# expr: f
# env: <environment: R_GlobalEnv>
lazy(lm)
# <lazy>
# expr: function (formula, data, subset, weights, na.action, method = "qr", ...
# env: <environment: R_GlobalEnv>
substitute
がlmで動作するようです。
select_happy<- function(df, col){
col <- substitute(col) # <- substitute() instead of lazy()
fo <- interp(~x, x=col)
select_(df, happy=fo)
}
select_happy(df, lm)
# happy
# 1 7
# 2 8
# 3 9
しかし、the vignette on lazyeval
を読んだ後、lazy
がsubstitute
のための優れた代替として使用すべきであると思われます。さらに、通常のselect
関数は正常に機能します。
select(df, happy=lm)
# happy
# 1 7
# 2 8
# 3 9
私の質問はどのように私はそれがselect()
が行うすべての方法で動作するようにselect_happy()
を書くことができるのですか?私はスコープと非標準的な評価の周りに私の頭を包んで苦労している。より一般的には、これらの問題やその他の問題を回避できるdplyrを使ったプログラミングのための強固な戦略は何でしょうか?
編集
私はdocendoのdiscimusのソリューションをテストし、それは素晴らしい仕事が、私は機能のために、むしろドットよりも、引数を使用する方法があるかどうかを知りたいです。 interp()
を使用できることも重要だと思います。これは、先にリンクした記事のように、入力をより複雑な数式に入力したい場合があるためです。問題の核心は、とは違ってlazy_dots()
が式を取り込んでいるという事実になると私は思う。私はなぜ彼らが異なったふるまいをしているのか、lazy()
を使用してlazy_dots()
と同じ機能を利用する方法を理解したいと思います。
lazy_dots()
が動作しないと、それは同じになるようにしても
lazy()
ため
FALSE
に
.follow__symbols
を変更
g <- function(...){
lazy_dots(...)
}
h <- function(x){
lazy(x)
}
g(lm)[[1]]
# <lazy>
# expr: lm
# env: <environment: R_GlobalEnv>
h(lm)
# <lazy>
# expr: function (formula, data, subset, weights, na.action, method = "qr", ...
# env: <environment: R_GlobalEnv>
。
lazy
# function (expr, env = parent.frame(), .follow_symbols = TRUE)
# {
# .Call(make_lazy, quote(expr), environment(), .follow_symbols)
# }
# <environment: namespace:lazyeval>
lazy_dots
# function (..., .follow_symbols = FALSE)
# {
# if (nargs() == 0)
# return(structure(list(), class = "lazy_dots"))
# .Call(make_lazy_dots, environment(), .follow_symbols)
# }
# <environment: namespace:lazyeval>
h2 <- function(x){
lazy(x, .follow_symbols=FALSE)
}
h2(lm)
# <lazy>
# expr: x
# env: <environment: 0xe4a42a8>
私はちょうど何をすべきかについて固執しています。
一つのオプションは、書き込みselect_happy
標準
select
機能とほぼ同じようにするかもしれ
@Henrik私が何を意味するのかであります!それでもエラーは出力され、問題は全体的に同じです。私は修正を反映するために質問を更新しました。 –