【问题标题】:Combining expressions in R在 R 中组合表达式
【发布时间】:2013-02-21 02:56:18
【问题描述】:

我正在尝试将 R 中的多个表达式组合成一个表达式。理想情况下,我可以这样做:

g <- expression(exp(a[1]*x)/(1 + exp(a[1]*x)))
h <- expression(exp(a[2]*x)/(1 + exp(a[2]*x)))
c <- expression(g * h)

其中a 是给定的数据向量,x 是唯一的未知数(并且在所有表达式中都是相同的未知数)。 c 会返回

R> c
expression(exp(a[1]*x)/(1 + exp(a[1]*x)) * exp(a[2]*x)/(1 + exp(a[2]*x)))

现在,当我这样做时,我会得到

R> c
expression(g * h)

我想要一个方程


(来源:lehrfeld.me

我可以在其中插入一些向量a 以获得x 的函数。我在这里做错了什么?

【问题讨论】:

  • R 不是符号代数程序。您应该注意@thelatemail 和 mnel。 R 是一种函数式语言。

标签: r expression


【解决方案1】:

不要使用表达式,使用函数。

据我所知,以下将做你想做的事

# a function for a vector `x` and single value `a`
func <- function(x,a) { (exp(1)^(a*x)/(1 + exp(1)^(a*x))) }
# a function for  a vector `x` and vector length 2 for `a`
foo <- function(x, a){func(x,a[1]) * func(x, a[2])}

# call the function to calculate what you want.

foo(x,a)

如果您希望 expression 与此相关联,以便您可以绘制等式的文本,以下将起作用

expr <- expression(exp(1)^(a*x)/(1 + exp(1)^(a*x))

g <- do.call(substitute, list(as.list(expr)[[1]], env= list(a=3)))
h<- do.call(substitute, list(as.list(expr)[[1]], env= list(a=2)))
'%c%' <- function(a,b) bquote(.(a) %*% .(b))

fooExpr <- g %c% h

【讨论】:

    【解决方案2】:

    这是一个古老的问题,但令人惊讶的是,没有给出简单的答案。正如评论中所说,“R 不是符号代数程序”;但是,R 具有操作表达式的所有必要手段。我不知道如何使用expressions(从技术意义上说,请参阅?expression)但使用calls 非常容易:

    g <- quote(exp(a[1]*x)/(1 + exp(a[1]*x)))
    h <- quote(exp(a[2]*x)/(1 + exp(a[2]*x)))
    substitute(g*h, list(g=g, h=h))
    # exp(a[1] * x)/(1 + exp(a[1] * x)) * (exp(a[2] * x)/(1 + exp(a[2] * x)))
    

    可能有更简单的方法来实现您想要的(可能使用函数),但这是合并两个“调用”(即 R 向导定义的“口语”意义上的表达式)的最简单方法。

    【讨论】:

      【解决方案3】:

      你可能想要一个函数而不是我认为的表达式:

      newfunc <- function(x) {
        (exp(1)^(2*x)/(1 + exp(1)^(2*x))) *
        (exp(1)^(3*x)/(1 + exp(1)^(3*x)))
      }
      
      a <- 1:10
      
      newfunc(a)
      [1] 0.8390245 0.9795856 0.9974043 0.9996585 0.9999543 0.9999938 0.9999992
      [8] 0.9999999 1.0000000 1.0000000
      

      如果你想明确地将多个函数链接在一起,你可以这样做:

      newfunc1 <- function(x) {
        (exp(1)^(2*x)/(1 + exp(1)^(2*x)))
      }
      
      newfunc2 <- function(x) {
        (exp(1)^(3*x)/(1 + exp(1)^(3*x)))
      }
      
      newfunc1(a) * newfunc2(a)
      

      请记住,正如 ?expression 中的帮助文件所说:

        ‘Expression’ here is not being used in its colloquial sense, that
        of mathematical expressions.  Those are calls (see ‘call’) in R,
        and an R expression vector is a list of calls, symbols etc, for
        example as returned by ‘parse’. 
      

      【讨论】:

      • 感谢您的回复。这样做的问题是,在我检查数据向量a 之前,我并不确切知道每个单独的表达式将采用的形式。我发布了我的问题的一个非常简化的版本,即我想动态指定组合表达式,并且表达式中的每个术语(我在上面只显示了两个)可以采用三种可能的形式之一。所以我实际上需要边做边构建它。
      • @psychometriko - 我不确定使用函数方法会有什么问题。只需随时添加或编辑newfunc 中的一行,直到您满意为止。
      【解决方案4】:

      您可以定义一个二进制函数来以一种有点 hacky 的方式组合 expression 对象 - 获取它们的字符表示,用 * 粘贴它们,然后重新解析它:

      "%c%" &lt;- function(x, y) parse( text=paste(x, "*", y) )

      例如,在调用g %c% h 时提供所需的输出。

      编辑:已更新答案以纠正先前的错误;谢谢mnel!

      【讨论】:

      • 非常感谢您的想法!一旦我有机会对此进行测试,希望明天,我会将其标记为答案。
      • 这行不通!它创建了一个expression('exp(a[1]*x)/(1 + exp(a[1]*x)) * exp(a[2]*x)/(1 + exp(a[2]*x))'),它与expression(exp(a[1]*x)/(1 + exp(a[1]*x)) * exp(a[2]*x)/(1 + exp(a[2]*x)) 不同。当然不会让你传递一个向量 ax 来获得一个你可以在 R 中评估的 x 函数
      • 谢谢。我很接近,但你的解决方案肯定更好。
      【解决方案5】:

      使用 rlang 从其他表达式创建表达式比使用基本 R 更直接 (IMO)。使用 !! (bang-bang) 强制评估表达式中的对象。

      library(rlang)
      
      a <- c(2, 3)
      g <- expr(exp(!!a[1] * x) / (1 + exp(!!a[1] * x)))
      h <- expr(exp(!!a[2] * x) / (1 + exp(!!a[2] * x)))
      c <- expr(!!g * !!h)
      c
      #> exp(2 * x)/(1 + exp(2 * x)) * (exp(3 * x)/(1 + exp(3 * x)))
      

      reprex package (v0.3.0) 于 2020-03-21 创建

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-12
        • 1970-01-01
        • 1970-01-01
        • 2012-03-02
        相关资源
        最近更新 更多