从与表达式相同的值中获取R表达式(...)

时间:2015-03-20 14:39:36

标签: r expression

我正在搜索函数get_expr <- function(val),返回与原始表达式相同的表达式,即identical(get_expr(c(1,2)), expression(c(1,2))必须为真。

我已经问了一个问题,要求少一点:Getting an R expression from a value (simlar to enquote)有了这个,就可以从大多数情况下的行为中得到一个表达式,就像原始情况一样 - 但遗憾的是并非在所有情况下。无论是在我的问题工作中还是在答案中建议的解决方案中,语句identical(get_expr(c(1,2)), expression(c(1,2))都评估为TRUE。

示例:

e1 <- expression(c(1,2))
get_expr <- function(val) as.expression(list(val))
e2 <- get_expr(c(1,2))

控制台输出以及e1e2的评估完全相同。但是我们得到了

> identical(e1,e2)
[1] FALSE

差异似乎是略有不同的结构:

> e1[[1]]
c(1, 2)
> e2[[1]]
[1] 1 2

现在我攻击了一个新的解决方法:

get_expr2 <- function(val) {
  if (length(val) <= 1) {
    return(as.expression(val))
  } else {
    if (is.list(val)) op <- quote(list)
    else if (is.vector(val)) op <- quote(c)
    return(as.expression(as.call(c(list(op), as.list(val)))))
  }
}

现在我知道identical(expression(c(1,2)), get_expr2(c(1,2)))返回true。

但我对此并不满意......鉴于结构稍微复杂一点,这种方法失败了:identical(expression(list(1, c(1,2))), get_expr2(list(1, c(1,2))))返回false。看来,对于我的方法,我必须先知道值的结构......

我认为应该有一个更智能的解决方案将值转换为精确的表达式对应物?

编辑(21-03-15):我忘了说a<-c(1,2); get_expr(a)也应该有效。

避免大量案件的单线解决方法是

get_expr3 <- function(x) parse(text=deparse(x))

但这更像是一场黑客......

1 个答案:

答案 0 :(得分:0)

您正在寻找substitute

R> get_expr <- function(x) as.expression(substitute(x))
R> identical(get_expr(c(1,2)), expression(c(1,2)))
[1] TRUE
R> identical(expression(list(1, c(1,2))), get_expr(list(1, c(1,2))))
[1] TRUE

您还可以使用match.call

get_expr <- function(x) as.expression(match.call()$x)

但是警告:多行表达式失败。

R> (x <- get_expr({a<-1;b<-2}))
expression({
    a <- 1
    b <- 2
})
R> (y <- expression({a<-1;b<-2}))
expression({
    a <- 1
    b <- 2
})
R> identical(x, y)
[1] FALSE