r - 如何在计算表达式时自定义符号的搜索路径?

标签 r expression eval environment

在某些情况下我需要自定义一些符号的搜索路径。例如,当我计算表达式 f(x,y,z) 时,我需要在以下环境链中对其进行评估:

首先,在env1中找到符号其中 xy已定义,但 fz不是。

然后,找到fzenv2两者均已定义。

问题是 env1env2不是我自己定义的,也就是说,当我可以使用它们时,它们的父环境是确定的。

对于这种特定情况,我可以手动调用 existsget找到那些符号。但这似乎不适用于用户输入的表达式且事先未知的一般情况。

是否有一种适用于任何用户输入表达式的通用且快速的方法,以便在一系列给定环境中使用 inherits = FALSE 对该表达式进行求值?除了最后一个。假设函数名为 evalc那么用法可能是:

evalc(quote(f(x,y,z)), env1, env2, env3)

其中给出了一系列环境。对于 env1env2 , 使用 inherits = FALSE 查找符号;但对于 env3使用 inherits = TRUE 查找符号.

最佳答案

1) 你真的需要inherits = FALSE吗?否则这有效:

esub <- function(...) do.call(substitute, list(...))
evalc <- function(expr, env1, env2, env3 = parent.frame()) {
   eval(esub(esub(expr, env1), env2), env3)
}

 # test
 env1 <- list2env(list(x = 1, y = 2))
 env2 <- list2env(list(f = function(...) list(...), z = 3))
 evalc(quote(f(x, y, z)), env1, env2)

2) 如果您确实需要 inherits = FALSE,那么我们将每个环境复制到一个新环境中,该新环境以任何空环境作为父环境:

evalc <- function(expr, env1, env2, env3 = parent.frame()) {
   e1 <- list2env(as.list(env1))
   e2 <- list2env(as.list(env2))
   parent.env(e1) <- parent.env(e2) <- emptyenv()
   eval(esub(esub(expr, e1), e2), env3)
}

3) 如果我们有未知数量的环境:

evalc <- function(expr, ..., env = parent.frame()) {
   for(e in list(...)) {
      ee <- list2env(as.list(e))
      parent.env(ee) <- emptyenv()
      expr <- esub(expr, ee)
   }
   eval(expr, env)
}

4) 这是避免复制的另一种解决方案。它确实要求您能够修改 env1env2、...

的父级
evalc <- function(expr, ..., env = parent.frame()) {
   for(e in list(...)) {
      p <- parent.env(e)    
      parent.env(e) <- emptyenv()
      expr <- esub(expr, e)
      parent.env(e) <- p
   }
   eval(expr, env)
}

更新 添加了 2、3 和 4。

关于r - 如何在计算表达式时自定义符号的搜索路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25235152/

相关文章:

r - 在R中按月汇总行

python - base64 字符串的编译和求值

javascript - 使用 eval() 定义变量显示未定义错误

r - 如何计算每列的滚动平均值

r - 为 stat_density2d 图手动设置 scale_alpha

r - 如何在R中获得abline的梯度

javascript - 正则表达式在匹配的单词周围放置标签

syntax - 数学表达式的语法规则(无左递归)

Python:快捷条件表达式

r - dplyr 通过评估查找单元格值来改变特定列