R - 从字符串创建函数

标签 r expression

我在 Parlist section of the Expressions chapter in Advanced R 中遇到了下面的函数:

make_function <- function(args, body, env = parent.frame()) {
  args <- as.pairlist(args)

  eval(call("function", args, body), env)
}

该函数允许用户从其组成部分构造函数:形式参数列表、函数体和环境。例如

add <- make_function(alist(a = 1, b = 2), quote(a + b))
add
function (a = 1, b = 2) 
a + b

class(add)
[1] "function"

我想知道是否可以修改该函数以允许用户为 body 参数输入字符串?我尝试过 parse(text = 'a + b') 但这会返回一个表达式,而不是 quote(a + b) 中的调用:

class(quote(a + b))
[1] "call"
class(parse(text = 'x^m'))
[1] "expression"

有没有办法从字符串构造一个call对象?

最佳答案

您通常应该避免解析用户输入的任意字符串。通常,可以通过适当的软件设计来避免这种情况。

无论如何,只需从表达式中提取语言即可:

make_function(alist(a = 1, b = 2), parse(text = 'a^b')[[1]])

编辑:

只是为了展示如何检查白名单(不涉及正则表达式):

whitelist <- c("+", "*", "-", "/", "^", "**", "%%", "%/%", "sin", "cos", "tan", "abs") #etc.
expr <- parse(text = "cos(x)^sin(x)*abs(x)")
foo <- function(e) if (length(e) > 1) lapply(as.list(e), foo) else return(e)
funs <- unlist(foo(expr[[1]]))
funs <- funs[vapply(funs, function(x) {x <- eval(x); is.function(x) | is.primitive(x)}, FUN.VALUE = TRUE)]
all(vapply(funs, function(x) as.character(x) %in% whitelist, FUN.VALUE = TRUE))

在公共(public) Shiny 应用程序中解析和评估任意代码存在安全风险。此检查确保只能使用一组预定义的函数。如果您不回避较小的风险,您可以使用黑名单来代替(禁止诸如 systemsystem2shell 等功能。 )。

关于R - 从字符串创建函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58389523/

相关文章:

R - 如何获得两点之间的平滑曲线?

r - 在R中创建动态文件名时遇到问题

c++ - 最有效和最简单的表达式评估 C++ 解决方案

c# - 从 MemberExpression 和 Constant 创建 Func<T, bool>

spring - 如何以编程方式解析 spring 安全表达式(例如在某些 Controller 中)

为 R 中数据框的每一行返回缺少 (NA) 数据的列名列表

r - 通过连续的冒号从字符串中提取字符

r - 双泊松分布中的最大似然

c# - 如何使用 System.Linq.Expressions.Expression 根据 child 进行过滤?

SSIS 派生列表达式