2011-12-13 3 views
20

あなたが実行している場合:R関数をコード化して、他の引数の変数を 'データ'で調べる方法を知っていますか?

mod <- lm(mpg ~ factor(cyl), data=mtcars) 

をLMはMPGとCYLの両方を見つけるためにmtcarsで見て知っているので、それは動作します。

まだmean(mpg)はmpgが見つからないので失敗しますので、mean(mtcars$mpg)を実行してください。

変数を 'データ'で調べるために関数をどのようにコード化しますか?

myfun <- function (a,b,data){ 
    return(a+b) 
} 

これは動作します:

myfun(mtcars$mpg, mtcars$hp) 

しかしで失敗します:

myfun(mpg,hp, data=mtcars) 

乾杯

+2

簡潔な回答を投稿するのに十分理解しているとは思いませんが、@Hadleyはhttps://github.com/hadley/devtools/wiki/Evaluationで説明しています。 – Chase

+0

乾杯、チェス、私は、ハドレーがこのように機能する一連の関数として心に浮かんだggplotを与えると、尋ねる人がいることを知っていました。今読むことができます。 – nzcoops

答えて

20

は私がmyfun()をコーディングする方法をです:

myfun <- function(a, b, data) { 
    eval(substitute(a + b), envir=data, enclos=parent.frame()) 
} 

myfun(mpg, hp, mtcars) 
# [1] 131.0 131.0 115.8 131.4 193.7 123.1 259.3 86.4 117.8 142.2 140.8 196.4 
# [13] 197.3 195.2 215.4 225.4 244.7 98.4 82.4 98.9 118.5 165.5 165.2 258.3 
# [25] 194.2 93.3 117.0 143.4 279.8 194.7 350.0 130.4 

あなたはwith()に精通している場合、それはほぼ正確で同じように動作することを見るのは興味深いです:両方のケースで

> with.default 
# function (data, expr, ...) 
# eval(substitute(expr), data, enclos = parent.frame()) 
# <bytecode: 0x016c3914> 
# <environment: namespace:base> 

を重要な考え方は、最初に引数として渡されたシンボルから式を作成し、評価の '環境'としてdataを使用してその式を評価することです。

substitute()のおかげで、最初の部分(たとえばa + bを式mpg + hpに変換する)が可能です。第2の部分は、eval()が美しく設計されており、評価環境としてdata.frameを取ることができるので可能です。

5

lmは、それが実際に構築するため、そのdata引数に見て、 "知っています"それ自身の呼び出しを使用してmodel.frameへの呼び出しベース。 lmのコードを見ると、必要な機械が最初の12行程度に表示されます。

あなた自身の目的でこれを複製することもできますが、必要が単純な場合は同じ程度に進む必要はありません。たとえば、

evalqをご覧ください。

3

これはまさにあなたが求めたもののようではありませんが、およそwith()がわからない場合は、このオプションがあります:

myfun <- function (a,b){ 
    return(a+b) 
} 
with(mtcars, myfun(mpg, hp)) 

あなたはこのためにMYFUNするdata引数を削除することができます。ここで

+0

乾杯、これは明らかに違反を意味しませんが、回避策を使用するよりも(ユーザーの簡素化のために)機能をより良くしようとしています。 – nzcoops

関連する問題