R (预)向功能工厂和内部提供变量
我正在读哈德利的书,并尝试一些东西。我正在尝试创建一个R (预)向功能工厂和内部提供变量,r,R,我正在读哈德利的书,并尝试一些东西。我正在尝试创建一个lazy闭包函数,该函数在其环境中返回一个带有提供的data.frame的函数,并将与一起使用,以便以后能够提供额外的函数参数 lazy <- function(dataframe, x) { function(FUN, x, ...) { with(dataframe, FUN(x = x, ...)) } } lz_factory <- lazy(mtcars, "mpg") lz_fact
lazy
闭包函数,该函数在其环境中返回一个带有提供的data.frame
的函数,并将与
一起使用,以便以后能够提供额外的函数参数
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")
我想我可以用替代品来解决这个问题,正如哈德利在这里用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
lazy这个函数怎么样
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)))
}
}
lazy这里是@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())
}
}
懒惰的圣洁的烟比我想象的要复杂。我对没有得到它感到不那么难过。很酷。如果有人有不同的方法,我会暂缓付款。我理解你的方法,但是,目前,我不会独自到达那里。@Tyler,我可能把它复杂化了。我没有花太多时间去减少它。另外,我不确定是否真的要将列名作为字符串传递。这可能会将一些substitute
调用更改为get
调用。因为即使在使用
的中,也不能使用字符串作为变量名。谢谢您的思考。我非常感激它,一直在享受和学习先进的R吨
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
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())
}
}