您已經在此示例方法中將「expression」指定爲第二個參數的類。因爲
NewVar=Petal.Width*Petal.Length
被解釋爲一個命名參數值爲
Petal.Width*Petal.Length
不會得到機會進行評估,以myfun第一個例子返回一個錯誤,因爲NewVar不是爭論對於這種方法或通用。
在第二個例子,我不知道是怎麼回事與封閉大括號,因爲我的錯誤與圖示不同:
錯誤myfun(光圈,{: 錯誤評估參數'y'爲函數'myfun'選擇方法:錯誤:找不到對象'Petal.Width'
但是,當我強制將表達式設置爲表達對象:
myfun(iris, expression(NewVar=Petal.Width*Petal.Length))
我認爲這隻能部分回答你的問題,因爲平凡地返回虹膜數據幀不是你想要的。該表達式沒有被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
這是一個版本,用於向數據添加一個變量列。幀:
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
再次,這實現了本質上是硬編碼的,即只有一個變量列將被添加到輸入數據幀中,儘管該變量列和表達式的名稱是任意的,並且作爲表達式提供。我敢肯定,有一個更好的,更一般的答案,可以評估y中的表達式,就好像它是transform()函數中的直接調用一樣,但我目前難以用什麼作爲適當的「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()。
經過多次試驗和錯誤之後,我想出了一種適用於真實的方法。首先表達對象轉換成與as.list()的列表,從而建立要與奇妙
do.call()
完整的例子調用看起來是這樣的:
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"
而且新data.frame對象「test」有我們想要的「NewVar」列。
請參閱SfDA的第399-402頁,其中Chambers描述了爲什麼要評估經過簽名測試的參數_must_。 –
@DWin:小心分享鏈接? sfDA聽起來對我來說並不熟悉,我想你不是在談論國家食品和藥物管理局... –
對不起。 John Chambers的「數據分析軟件」。作爲附加的一點,我注意到你的簽名值與參數名稱沒有關聯,而在這個例子中是格式。 (注意:在問題體中你還沒有變成'transform')。 –