当内部有嵌套函数时,如何在R中以编程方式创建函数?

时间:2019-08-23 17:52:30

标签: r metaprogramming rlang

我的目标是使用代码创建以下功能:

s <- c(x = 10)
a <- c(i = 3)

model <- function(s, a) {
  with(as.list(c(s, a)), {
    y <- x * i
    y * 10
  })
}

model(s, a)

结果应为300。

我正在解析其他软件,并且可以从该软件中提取方程式作为字符串。因此,我需要从这些字符串构造函数的主体。

我一直试图使用rlang库无济于事。

library(rlang)

func_body <- "with(as.list(c(s, a)), {
  y <- x * i
  y * 10
})";

foo <- new_function(
  exprs(s =, a = ),
  expr(!!parse(text = func_body))
)

有什么主意吗?

2 个答案:

答案 0 :(得分:5)

不确定在这里使用new_function的动机,但这会带来预期的输出:

library(rlang)

s <- (x = 10)
a <- (i = 3)

foo <- new_function(
  args = pairlist2(s =, a =),
  body = expr(
    with(as.list(c(s, a)), {
      y <- x * i
      y * 10
    })
  )
)

foo(s, a)
#[1] 300

如果主体是字符串,请使用parse_expr

foo2 <- new_function(
  args = pairlist2(s =, a =),
  body = parse_expr(
    "with(as.list(c(s, a)), {
      y <- x * i
      y * 10
    })"
  )
)

foo2(s, a)
#[1] 300

答案 1 :(得分:1)

使用基数R可以:

foo <- function(s, a){}
body(foo) <- parse(text=func_body)
foo(s, a)
#> [1] 300

仍在基数R中的另一种方法是:

foo <- as.function(c(alist(s=,a=), parse(text=func_body)[[1]]))
foo(s, a)
#> [1] 300

请注意,在您的示例中,根本没有使用sa的值,您只是使用了全局工作区中的x和i的值。您可能想要:

# cleanup
rm(s,a,x,i)
s <- c(x = 10)
a <- c(i = 3)
foo(s, a)
#> [1] 300