将R中的多个表达式组合成一个大表达式

时间:2015-06-02 18:30:22

标签: r expression eval

我是R表达式处理的新手。我遇到了以下问题。任何意见都表示赞赏。

我正在尝试生成两个单独的方程式并将它们组合成一个表达式并将其传递给算法以找到最佳值。

   OLD_PRICE    ELAST      Units    
 1  59.98        1.3        151     
 2  59.98        1.3        230     

代码:

for(i in 1:nrow(df)){
    o[i] = df$OLD_PRICE[i]
    el[i] = df$ELAST[i]
    u[i] = df$Units[i]
    assign(paste0("l",i),(substitute((x)*(1-(x-o)*el/o)*u,     list(o=o[i],el=el[i],u=u[i]))))
}

我能够生成以下两个方程式

l1 = (x) * (1 - (x - 59.98) * 1.3/59.98) * 151
l2 = (x) * (1 - (x - 59.98) * 1.3/59.98) * 230

我的目标函数看起来像这样

eval_obj_f <- function(x){eval(l1)+eval(l2)}

我想弄清楚如何动态地这样做。就像我有4个观察的不同数据集一样,如何生成我的目标函数,如下所示?

eval(l1)+eval(l2)+eval(l3)+eval(l4)

2 个答案:

答案 0 :(得分:0)

你需要使用真正的R expression,而目前这些不是表达式,而是call的。 (查看is.expressionclass)。我不喜欢数据帧的名称“df”,因为它也是一个函数名,所以我使用了“prdat”:

 o <- el <- u <- numeric(2)  # if they don't exist, then the loop errors out
 for(i in 1:nrow(prdat)){
     o[i] = prdat$OLD_PRICE[i]
     el[i] = prdat$ELAST[i]
     u[i] = prdat$Units[i]
     assign(paste0("l",i), as.expression(substitute(x*(1-(x-o)*el/o)*u, 
                                                   list(o=o[i],el=el[i],u=u[i]))))
                        }

l1
#expression(x * (1 - (x - 59.98) * 1.3/59.98) * 151) # how expressions appear when printed.
l2
#expression(x * (1 - (x - 59.98) * 1.3/59.98) * 230)
exprlist <- list(l1,l2)

eval_obj_f <- function(x){sum( sapply( exprlist, eval, envir=list(x=x) ) )}
eval_obj_f(2)
#[1] 1719.569

这看起来很笨重。我可能会apply - 在该数据帧上编写一个函数并对结果求和。我想尝试“语言计算” - 方法可能会很有趣,但是请考虑下面的代码,我认为这更符合“R-way”。似乎更紧凑......和富有表现力:

func <- function(x) {apply(prdat, 1, function(z) x*(1-
                                (x-z["OLD_PRICE"])*z["ELAST"]/z["OLD_PRICE"])*z["Units"] )}
> sum( func(x=2))
[1] 1719.569

这可能比仅使用您的代码更好(但仍然比第二种方法IMO更笨重):

exprvec <- expression()
o <- el <- u <- numeric(2)  
 for(i in 1:nrow(prdat)){
     o[i] = prdat$OLD_PRICE[i]
     el[i] = prdat$ELAST[i]
     u[i] = prdat$Units[i]
     exprvec[[i]] <- substitute(x*(1-(x-o)*el/o)*u, 
                                list(o=o[i],el=el[i],u=u[i]))
                        }  #substitute-value gets coerced to mode-expression
# Test
> eval_obj_f <- function(x){sum( sapply( exprvec, eval, envir=list(x=x) ) )}
> eval_obj_f(2)
[1] 1719.569

答案 1 :(得分:-1)

您可以使用省略号创建使用任意数量参数的函数:

eval_obj_f <-function(x,...){
  sum(sapply(...),function(expr) {eval(expr)})
}

对于我的例子,我将你的R表达式移动到列表

l=list()
for(i in 1:nrow(df)){  
  o = df$OLD_PRICE[i]
  el = df$ELAST[i]
  u = df$Units[i]
  l[[i]]=substitute((x)*(1-(x-o)*el/o)*u,list(o=o,el=el,u=u))
}

现在,您可以将列表传递给eval_obj_f函数,其值为&#39; x&#39;:

x=8.76
eval_obj_f (x,l)