首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >函数工厂r中的替换形式参数

函数工厂r中的替换形式参数
EN

Stack Overflow用户
提问于 2017-03-30 02:01:33
回答 3查看 230关注 0票数 2

我正在尝试创建一个函数工厂,使函数具有自定义的形式参数名。其思想是向工厂提供一个字符串,而工厂又在表单和返回函数的主体中替换它。我已经成功地使用了eval(解析(text=paste(),但是我在其他地方读到了这种糟糕的实践。如何才能获得相同的输出,同时又避免执行度量衡分析?

代码语言:javascript
运行
复制
MyLinearRateFunctions<-function(varX){

  eval(parse(text=paste("function(a,b,",
                    varX,
                    ") 1/(a + b*",
                    varX,
                    ")",sep="")
  ))

 }

(LinearRateMPG<-MyLinearRateFunctions('mpg'))

# function(a,b,mpg) 1/(a + b*mpg)
# <environment: 0x11c2f2a00>

(LinearRateCYL<-MyLinearRateFunctions('cyl'))

# function(a,b,cyl) 1/(a + b*cyl)
# <environment: 0x11e4cb908>

(LinearRateDISP<-MyLinearRateFunctions('disp'))

# function(a,b,disp) 1/(a + b*disp)
# <environment: 0x11e47eae8>
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-30 02:13:52

也许有一种更简洁的方法来达到这个目的,但有一个想法:

代码语言:javascript
运行
复制
fn <- function(x) {
    f <- eval(bquote(function(a, b) 1 / (a + b * .(as.name(x)))))
    formals(f) <- c(formals(f), setNames(alist(dummy = ), x))
    f
}

fn()的第一行中,我们使用bquote()x替换为数学表达式。我们需要对此进行评估(使用eval()),以便将其从调用转换为函数。然后在第二行中,我们将第三个参数添加到正式参数列表中。最后一行返回函数。

代码语言:javascript
运行
复制
fn("mpg")
# function (a, b, mpg) 
# 1/(a + b * mpg)
# <environment: 0x4f05c78>

fn("cyl")
# function (a, b, cyl) 
# 1/(a + b * cyl)
# <environment: 0x4f9ba28>

快速检查:

代码语言:javascript
运行
复制
fn("mpg")(1, 2, 3)
# [1] 0.1428571
1 / (1 + 2 * 3)
# [1] 0.1428571

并感谢您要求一个更好的替代eval(parse(text = ...)),这肯定是不好的做法。

票数 1
EN

Stack Overflow用户

发布于 2017-03-30 02:51:01

这里有一个使用pryr::make_function的替代方案。这有一个额外的好处,就是将函数“环境”设置为“函数工厂”调用的调用环境。

代码语言:javascript
运行
复制
fn2 <- function(x) {
  fbody <- bquote(1 / (a + b * .(as.name(x))))
  fargs <- setNames(alist(,,),c('a','b',x))
  pryr::make_function(fargs,fbody, env=parent.frame(2))
}

虽然这看起来避免了对eval的调用,但它只是隐藏在make_function中。

票数 1
EN

Stack Overflow用户

发布于 2017-03-30 03:29:45

这只使用基R而不使用eval。首先设置要用作模板的函数,然后更改表单、设置主体和设置环境。

代码语言:javascript
运行
复制
factory <- function(x, envir = parent.frame()) {
  fun <- function(a, b, x) {}
  names(formals(fun))[[3]] <- x
  body(fun) <- substitute(1/(a+b*x), list(x = as.name(x)))
  environment(fun) <- envir
  fun
}

# test
myfun <- factory("m")

给予:

代码语言:javascript
运行
复制
> myfun
function (a, b, m) 
1/(a + b * m)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43107213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档