在R中替换=的LHS

时间:2014-09-20 02:57:30

标签: r dplyr substitution

我想替换" ="的LHS。在R中的表达式中。在我个人的情况下,我需要它来确保以下内容创建一个数据框中尚不存在的变量

df %>% mutate(v = mean(w))

我尝试eval(substitute())但LHS未被替换

eval(substitute(df %>% mutate(v = mean(w)), list(v = as.name("id"))))
 #similarly in a list
eval(substitute(l <- list(v=1:10),list(v=as.name("id"))))
l
$v
[1]  1  2  3  4  5  6  7  8  9 10

为什么不能通过评估/替代替换v?什么是最好的解决方法?

1 个答案:

答案 0 :(得分:3)

1)eval / parse 创建一个cmd字符串,解析并评估它:

f2 <- function(DF, x, env = parent.frame()){
  cmd <- sprintf("mutate(%s, %s = mean(v1))", deparse(substitute(DF)), x)
  eval(parse(text = cmd), env)
}

f2(DF, "v1_name")

  v1 v1_mean
1  1       2
2  2       2
3  3       2
... etc ...

2)eval / as.call 另一种方法是构建一个列表,将其转换为一个调用并对其进行评估。 (这也是dplyr中mutate_each_q采用的方法。)

f3 <- function(DF, x, env = parent.frame()) {
    L <- list(quote(mutate), .data = substitute(DF), quote(mean(v1)))
    names(L)[3] <- x
    eval(as.call(L), env)
}

f3(DF, "v1_name")

3)do.call 我们在先前的解决方案中形成一个等于列表最后两个组件的列表,然后使用do.call

f3 <- function(DF, x, env = parent.frame()) {
    L <- list(.data = substitute(DF), quote(mean(v1)))
    names(L)[2] <- x
    do.call(mutate, L)
}

f3(DF, "v1_name")

Upodate 添加了其他解决方案。