返回函数的代码

Pat*_*ckT 4 parsing r shiny

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

如何获得以下效果:

f <- function(x = 1){x^2}
miracle(f)
[1]  "x^2"
Run Code Online (Sandbox Code Playgroud)

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

textInput(inputId = "inFun", label = h4("Enter a function:"), value = "x^2")
Run Code Online (Sandbox Code Playgroud)

这不是:

textInput(inputId = "inFun", label = h4("Enter a function:"), value = f)
Run Code Online (Sandbox Code Playgroud)

似乎我需要在价值的rhs上使用类似"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
Run Code Online (Sandbox Code Playgroud)

这有内置功能吗?

Pat*_*ckT 9

我想根据RomanLuštrik的评论回答我自己的问题,提出改进建议,而不是提出我的微不足道的"积分".

罗马建议使用函数体(),这是我从未听说过的.这里是body()做给f:

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

> body(f)
{
    x^2
}
Run Code Online (Sandbox Code Playgroud)

大括号是不需要的,所以我进一步搜索.我设法摆脱了大括号:

> gsub(' {2,}','',deparse(body(f))[2])
[1] "x^2"
Run Code Online (Sandbox Code Playgroud)

因此,上述问题回答了我自己的问题.但是有更优雅和更短的方式吗?

在罗曼建议使用之后body(),我偶然发现了joran,hadley和其他几个人给出的一个模板:

如何以编程方式创建R函数?

它解释了如何从参数列表,正文和环境以编程方式创建函数.因此,我决定f使用这3个原语来构造我的函数,并从内部调用body来调用body 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)
Run Code Online (Sandbox Code Playgroud)

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

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

它的工作原理!

我打算写value = gBody一些东西或其他东西,但我的第一次成功来了deparse(body(gFun)),所以这就是我现在正在使用的东西.

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

谢谢罗马:如果你写自己的答案,我会接受你的.