【问题标题】:Return a function's code返回函数的代码
【发布时间】:2014-01-15 09:26:52
【问题描述】:

这似乎是一个基本问题,但我似乎无法在 stackoverflow 上找到答案。

如何获得如下效果:

f <- function(x = 1){x^2}
miracle(f)
[1]  "x^2"

上下文是一个闪亮的应用程序(由 RStudio 打包),其中我有一个 textInput() 函数,我为其提供了一个初始值 x^2。虽然这有效:

textInput(inputId = "inFun", label = h4("Enter a function:"), value = "x^2")

这不是:

textInput(inputId = "inFun", label = h4("Enter a function:"), value = f)

看来我需要像“x^2”这样的值。

以下是我尝试过的几种变体的代表性示例:

eval(parse(text = f))
Error in as.character(x) : 
  cannot coerce type 'closure' to vector of type 'character'

f(x = "x")
Error in x^2 : non-numeric argument to binary operator

`f`
function(x){x^2}

f(x = `x`)
Error in f(x = x) : object 'x' not found

这个有内置函数吗?

【问题讨论】:

  • body(f) 呢?
  • 可以调整标题吗?没有把答案写在标题里?

标签: r parsing shiny


【解决方案1】:

我想根据 Roman Luštrik 的评论回答我自己的问题,以邀请改进建议,而不是提高我微薄的“分数”。

Roman 提出了我从未听说过的函数 body()。这是body()f 所做的:

f <- function(x = 1){x^2}

> body(f)
{
    x^2
}

大括号是不需要的,所以我进一步搜索了一点。我设法用这个摆脱了大括号:

> gsub(' {2,}','',deparse(body(f))[2])
[1] "x^2"

因此,以上内容回答了我自己的问题。但是有没有更优雅、更短的方法呢?

按照 Roman 的使用 body() 的建议,我看到了 joran、hadley 和其他几个人的出色回答,它为我提供了一个模板:

How to create an R function programmatically?

它解释了如何从参数列表、主体和环境以编程方式创建函数。因此,我决定用这 3 个原语构造我的函数 f,并从闪亮的 textInput 内部调用主体。

所以我把它放在我的global.R 文件中(小型大写字母g 是全球的简写)

# Convenience function
make.function <- function(args = alist(a = 1, b = 2), body = quote(a + b), 
                          env = parent.frame()) {
  subs <- list(args = as.pairlist(args), body = body)
  eval(substitute(`function`(args, body), subs), env)
}
gArg <- alist(a = 1, b = 2)
gBody <- quote(a + b)
gFun <- make.function(gArg, gBody)

然后在我的server.R 文件中,我有:

textInput(inputId = "inFun", label = h4("1. Enter a function:"), 
          value = deparse(body(gFun)))

而且它有效!

我本来打算写value = gBody 或类似的东西,但我的第一个成功来自deparse(body(gFun)),所以这就是我现在使用的。

使用make.functionglobal.R 中生成“静态”函数当然是矫枉过正,但我​​在server.R 内的其他地方使用make.function 来处理用户提供的参数和主体以创建新的函数并绘制它们,所以这是一个非常有用的函数。

谢谢 Roman:如果你自己写答案,我会接受你的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    • 2020-05-24
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多