(R) 如何通过组合较短的变量表达式来编写更大的表达式?

(R) How can a bigger expression be written by combining shorter variable expressions?

简要介绍,我有多个数据文件可以通过基于数学方程的模型进行拟合,这些数学方程是其他较短数学方程的组合(通过求和、乘法等...)。

例如,我有三个短方程:

expression1 <- exp(x)
expression2 <- exp(x^2)
expression3 <- exp(1/x)

因为每个数据文件都有自己更大的表达式,可以产生更好的拟合度,所以我希望能够生成这些更大的表达式作为更短表达式的组合。

我想要的是能够写出这样的东西:

expression1(1) + expression1(2) * expression2(3) + expression2(1)

并得到:

x1 + x2 * x3^2 + 1/x1

稍后我将使用这个更大的方程来找到更适合一个数据文件的值 x1、x2、x3。

exp 是指数函数,因此您的代码并不像您认为的那样工作。要使这样的东西起作用,可能需要使用 printOps 方法创建一个新的 S3 class:

make_exp <- function(expr) {
  expr <- match.call()$expr
  function(x) structure(list(val = do.call(substitute, list(expr))), 
                        class = "ex")
}

print.ex <- function(x, ...) print(x$val)

Ops.ex <- function(e1, e2) structure(list(val = call(.Generic, e1$val, e2$val)),
                                      class = "ex")

这允许

expression1 <- make_exp(x)
expression2 <- make_exp(x^2)
expression3 <- make_exp(1/x)

expression1(x1) + expression2(x2) * expression3(x3)
#> x1 + x2^2 * (1/x3)

1) 大概你指的是表达式而不是 exp。进行更改,我们定义 e1、e2、e3 和 e。 esub 是一个函数,它用表达式中的另一个变量名替换变量名。同名包中的 gsubfn 与 gsub 类似,除了第二个参数可以是一个函数(可能像我们在这里那样使用公式表示法表示),它将模式中的捕获组作为参数并用功能。我们 deparse e,使用 gsubfn 并将其解析回来。

library(gsubfn)

e1 <- expression(x)
e2 <- expression(x^2)
e3 <- expression(1/x)
e <- expression(e1(1) + e1(2) * e2(3) + e2(1))

esub <- function(expr, env) do.call("substitute", list(expr, env))
g <- gsubfn("(\w+)[(](\w+)[)]", 
  ~ deparse(esub(get(x)[[1]], list(x = as.name(paste0("x", y))))), 
  deparse(e))
parse(text = g)[[1]]
## expression(x1 + x2 * x3^2 + x1^2)

2) 如果希望使用字符串而不是表达式,它甚至更短:

library(gsubfn)

s1 <- "x"
s2 <- "x^2"
s3 <- "1/x"
s <- "s1(1) + s1(2) * s2(3) + s2(1)"

gsubfn("(\w+)[(](\w+)[)]", x + y ~ gsub("\bx\b", paste0("x", y), get(x)), s)
## [1] "x1 + x2 * x3^2 + x1^2"