如何在长表达式中引用数据框中的多个变量

how to reference many variables inside dataframe in long expression

我有以下df

> structure(f)
   p c  at cu z   m  A   ps dc w al  W    b  t  s  u re fs1 fs2 uc
1 21 7  12 43 1 0.5 10 22.3  5 5  8 NA 0.782 NA NA NA NA  NA  NA NA

和另一个包含 expressions/formulas 的 df 来计算 f

中的 NA 值
> structure(formulas)
   W           t
2 p*z*al p*z*sin(b)
       s       u         re         
2 p*z*cos(b) m*ps*z c+((s-u)*tan(at)

f 可能有多行,所以我只想将每个公式应用于每一列的所有行。 例如计算 W 我可以尝试

f$W=f$p*f$z*f$al

不过我想知道是否有办法将这一切自动化。我想转换公式中的表达式,然后应用它们来计算 f 中的相应变量。有没有一种方法可以在评估表达式时不重复 df$ 来引用 df 中的列? 我知道我可以使用 eval(parse(text="formulas[1,1]")) 将我的字符串变成一个表达式,但在这里我正在处理整个 df 列。

编辑,感谢 Frank,事实证明这种方法不必要地复杂,因为 eval 可以接受 envir 参数。

dat <- data.frame(a=1:5,b=5:1)

因此,我们可以这样写公式:

formulas = quote(data.frame(a_plus_b = a+b, a_min_b = a-b))

评估就很容易了:

out <- cbind(dat, eval(formulas, dat))


 > out
  a b a_plus_b a_min_b
1 1 5        6      -4
2 2 4        6      -2
3 3 3        6       0
4 4 2        6       2
5 5 1        6       4

使用字符串的旧方法:

formulas <- data.frame(a_plus_b="a+b",
                       a_min_b = "a-b",stringsAsFactors=F)

out <- cbind(dat,lapply(formulas, function(x){with(dat, eval(parse(text=x)))}))

这是我对这种 data.table 方式的看法。可能也可以摆脱 for 循环。但不知何故,它对我不起作用。如果我找到方法会更新。

df <- data.table(x = rnorm(10), y = rnorm(10), z = NA, w = NA)
df2 <- data.table(x = NA, y = NA, z = "cos(x) + sin(y)", w = "x * y")
varnames <- colnames(df2)[!sapply(df2[1,], is.na)]
for(i in varnames){
  df[,c(i) := with(df, eval(parse(text = with(df2, get(i)))))]
}

dplyr方式:

require(dplyr)
f <- f %>% mutate(W = p*z*al, t = p*z*sin(b), s = p*z*cos(b),
                  u = m*ps*z, re = c+((s-u)*tan(at))