这似乎是一个基本问题,但我似乎无法在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)
这有内置功能吗?
我想根据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和其他几个人给出的一个模板:
它解释了如何从参数列表,正文和环境以编程方式创建函数.因此,我决定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来创建新函数并绘制它们,所以它是一个非常有用的函数.
谢谢罗马:如果你写自己的答案,我会接受你的.
| 归档时间: |
|
| 查看次数: |
158 次 |
| 最近记录: |