将n *表达式*列表应用于数据框的每一行?

时间:2015-06-23 10:31:19

标签: r apply lapply mapply

简而言之,我有一个表达式列表,我想要应用于数据帧的每一行。这与this question非常相似,但有一个细微差别,我没有函数列表,但有一个表达式列表。这就是我的尝试:

我有一个方程术语的数据框,我传递给paste以形成表达式的文本字符串:

# build a test dataframe
a <- c(10, 11, 12)
b <- c(0.5, 06, 0.7)
c <- c(300, 400, 500)
d <- c(1000, 2000, NA)
p <- c(1.32, 1.37, 1.43)
m <- c(0.45, .55, .65)
params <- data.frame(a, b, c, d, p, m)

# create vector of expressions
ff.txt <- paste(params$a, "*2 + ",
    params$b, "*3 + ",
    params$c, "*4 + ",
    params$d, "*5 * ",
    "x * ", 
    params$p, " * ",
    params$m, 
    sep = "")

这将返回存储为文本的表达式向量,例如“10 * 2 + 0.5 * 3 + 300 * 4 + 1000 * 5 * x * 1.32 * 0.45”。

然后我编写了一个函数,使用parse将文本表达式转换为R表达式:

funs.list <- lapply(funs.txt, function(x) parse(file = "", text = x))

...其中funs.txt是存储为文本的表达式的向量。

现在,这是我遇到困难的地方。想象一下funs.list包含两个表达式。如果我这样做:

lapply(funs.list, eval, envir = list(x=c(7, 60)))

...我得到了一个2x2矩阵,我只希望答案在对角线上。 (最终,我将会有大约1,000个表达式,这些表达式将作为优化的一部分重复调用,因此不需要额外的计算工作。)

我尝试过的另一种方法是:

mapply(do.call, funs.list, lapply(params, list))

...但是我从do.call收到'what' must be a character string or a function的错误消息。

有关从哪里开始的任何建议?

2 个答案:

答案 0 :(得分:2)

如果我理解正确,你想要用x的第一个值来评估第一个表达式,用第二个值来评估第二个表达式。

你可以这样做:

mapply(function(ex, x) eval(ex, envir = list(x = x)), funs.list[1:2], c(7, 60))

答案 1 :(得分:2)

我觉得定义一个与你的代数表达式相对应的自定义R函数并在行模式中使用apply()函数(你在原始问题中似乎忽略了它)是一个更好的设计决策。 。此函数也会将x作为输入,因此我还cbind x向量到原始数据框。

exp <- function(a, b, c, d, p, m, x) {
           result <- 2*a + 3*b + 4*c + 5*d*x*p*m
           return(result)
       }

x <- c(1, 2, 3)
params <- cbind(params, x)

output <- apply(params, 1, function(x) {
                               exp(x['a']], x['b'], x['c'], x[["d"]],
                                   x['p'], x['m'], x['x'])
                           })