この例のメソッドでは、2番目の引数のクラスとして "expression"を指定しました。
NewVar=Petal.Width*Petal.Length
がNewVarが引数ではありませんので、評価する機会を得ることはありません値
Petal.Width*Petal.Length
とMYFUNする名前付き引数として解釈されているので、最初の例はエラーを返しますこのメソッドまたは汎用の場合2番目の例では
私のエラーが示されたものと異なるので、私は、閉じ中括弧で何が起こっているかわからないんだけど:myfunはつぎで
エラー(アイリス、{:評価で エラーエラー:オブジェクト 'Petal.Width'が見つかりません。
しかし、私は式を強制するとエラーは発生せず、iris data.frameを出力として取得します。これは、関数 'myfun'表現オブジェクト:
myfun(iris, expression(NewVar=Petal.Width*Petal.Length))
虹彩のdata.frameを返すのは、あなたが望むものではなかったからです。式がtransform()によって正しく評価されていません。私はあなたが出力を一致させたい疑いが正確に以下のハードコーディングされたバージョンからの出力:
transform(iris, NewVar=Petal.Width*Petal.Length)
ここでは、evalを
z <- expression(NewVar = Petal.Width*Petal.Length)
test <- eval(z, iris)
head(test, 2)
を使用して式を評価する簡単な例である[1] 0.28 0.28
ここには、データに1つの可変列を追加するためのバージョンがあります。フレーム:
setGeneric('myfun',function(x,y)standardGeneric('myfun'))
setMethod('myfun',c('data.frame','expression'), function(x,y){
etext <- paste("transform(x, ", names(y), "=", as.character(y), ")", sep="")
eval(parse(text=etext))
})
## now try it.
test <- myfun(iris, expression(NewVar=Petal.Width*Petal.Length))
names(test)
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "種" "NewVar"
再び
head(test)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species NewVar
1 5.1 3.5 1.4 0.2 setosa 0.28
2 4.9 3.0 1.4 0.2 setosa 0.28
、この実装は有します変数列と式の名前は任意であり、式として提供されますが、1つの唯一の可変列が入力data.frameに追加されることは本質的にハードコードされています。私はtransform()関数の直接呼び出しであるかのように、yで保持されている式を評価する、より良い、より一般的な答えがあると確信していますが、現時点では、適切な "inverse式()への関数。
あなたが実際のyに派遣したくない場合は、標準では、...常にある:
setGeneric('myfun', function(x, ...) standardGeneric('myfun'))
setMethod('myfun', 'data.frame', function(x, ...){
transform(x, ...)
})
そして、これは素晴らしい作品。しかし、あなたの質問は、実際に表現オブジェクトにディスパッチすることに関するものでした。
以下は動作しませんが、近づいていると思います。おそらく誰かが中にジャンプし、いくつかの最終的な調整を行うことができます。
setGeneric('myfun', function(x, y) standardGeneric('myfun'))
setMethod('myfun',c('data.frame', 'expression'), function(x, y){
transform(x, eval(y, x, parent.frame()))
})
## try out the new method
z <- expression(NewVar = Petal.Width*Petal.Length)
test <- myfun(iris, z)
names(test)
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "種"
基本的には、 myfun()を呼び出したときに、式の "NewVar ="部分がtransform()に渡されませんでした。
多くの試行錯誤の末、私は実際に働く方法を考え出しました。
setGeneric('myfun', function(x, y) standardGeneric('myfun'))
setMethod('myfun',c('data.frame', 'expression'), function(x, y){
do.call("transform", c(list(x), as.list(y)))
})
# try out the new method
z <- expression(NewVar = Petal.Width*Petal.Length)
test <- myfun(iris, z)
names(test)
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
[6] "NewVar"
そして新しい:最初の完全な例は次のようになります素晴らしい
do.call()
にしたいコールを構築し、その後、)(as.listでリストに表現オブジェクトを変換data.frameオブジェクト "test"には、必要な "NewVar"カラムがあります。
SfDAの399-402ページを参照してください。ここで、Chambersは署名検証済みの引数を評価する必要がある理由を説明しています。 –
@DWin:リンクを共有してみませんか? sfDAは私には馴染みのないように聞こえ、国家食品医薬品局(State Food and Drug Administration)について話しているわけではないと思います... –
申し訳ありません。 John Chambersによる "データ解析用ソフトウェア"追加のポイントとして、私はあなたの署名値が引数名に関連付けられていないことに気付きましたが、例ではフォーマットです。 (注:あなたはまだ質問本体で 'transform'に変更していません) –