[英](Pre)supply variables to function factory and within
我正在閱讀哈德利的高級R並嘗試一些東西。 我試圖創建一個lazy
,與所提供的返回功能閉合功能data.frame
在其環境以及使用with
和能夠后來提供額外的功能參數。
lazy <- function(dataframe, x) {
function(FUN, x, ...) {
with(dataframe, FUN(x = x, ...))
}
}
lz_factory <- lazy(mtcars, "mpg")
lz_factory(mean)
lz_factory(cor, y="hp")
所以我期待數據幀是功能環境的一部分( browser
看起來確認)。 但是,變量名x
不供應,當我使用cor
作為第一個FUN
參數時,我無法提供新變量y
。 這與為使用非標准評估(NSE)的函數( with
)提供字符有關。 我希望哈德利叔叔為我感到驕傲,但我用eval
, parse
, substitute
所有返回的錯誤。 這意味着我不完全了解R如何處理事情。 我知道為什么它不起作用(NSE)但不知道如何使其工作。 這是錯誤:
> lz_factory(mean)
Error in FUN(x = x, ...) : argument "x" is missing, with no default
> lz_factory(cor, y="hp")
Error in is.data.frame(x) : argument "x" is missing, with no default
我想我可以使用替補來解決它,因為Hadley在這里用xyplot
顯示,但這也是一個失敗,如下所示:
lazy <- function(dataframe, default) {
function(FUN, x, ...) {
if (missing(x)) x <- default
eval(substitute(with(dataframe, FUN(x, ...))))
}
}
lz_factory <- lazy(mtcars, "mpg")
lz_factory(mean)
lz_factory(cor, y="hp")
> lz_factory(mean)
[1] NA
Warning message:
In mean.default("mpg") : argument is not numeric or logical: returning NA
> lz_factory(cor, y="hp")
Error in cor("mpg", y = "hp") : 'x' must be numeric
那么我怎樣才能使這個惰性函數工作呢:
lz_factory
創建的lz_factory
最好我想讓這個功能與之with
。 如果那是不可能的,那么知道為什么會很好。 最后一點,如果無法使用with
我怎樣才能使功能操作?
這是@ MrFlick函數的略微簡化版本:
lazy <- function(df, x_var = NULL) {
x <- substitute(x_var)
function(FUN, ...) {
call <- substitute(FUN(...))
if (is.null(call$x) && !is.null(x)) {
call$x <- x
}
eval(call, df, parent.frame())
}
}
關鍵是更好地利用substitute()
的功能,並通過直接使用eval避免with()
。
這個功能怎么樣
lazy <- function(dataframe, ...) {
pdots <- substitute(list(...))
if(is.null(names(pdots)) || names(pdots)[1]=="") {
names(pdots)[2]<-"x"
}
function(FUN, ...) {
dots <- substitute(list(...))[-1]
if (is.null(dots$x)) {
dots$x <- pdots$x
}
with(dataframe, do.call(FUN, as.list(dots)))
}
}
這允許您在沒有引號的mtcars中使用變量的名稱。 例如
lz_factory <- lazy(mtcars, mpg)
lz_factory(mean)
# [1] 20.09062
lz_factory(mean, x=hp)
# [1] 146.6875
lz_factory(cor, y=hp)
# [1] -0.7761684
在這里,我們使用額外的替換來確保我們得到延遲評估並允許您使用不帶引號的變量名稱。 with
將負責評估表達式。 我猜可能有辦法簡化這個,但至少它似乎有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.