【问题标题】:bquote and evalq unexpected behavior in R-3.2.1R-3.2.1 中的 bquote 和 evalq 意外行为
【发布时间】:2015-10-03 15:56:18
【问题描述】:

我刚刚更新到 R-3.2.1,并且之前在 R-3.1.2 上运行的代码遇到了错误(基于此 answer)。

例如:

test <- list(bquote(x <- 10))
fenv <- environment()
rapply(test, evalq, envir = fenv)

上述代码之前运行良好,但现在报错:

Error in eval(substitute(expr), envir, enclos) : object 'X' not found

预期的行为是在fenv 中定义x。我试图弄清楚如何继续,以便代码适用于当前和以前版本的 R(如果可能的话)。

有趣的是,eval 在 R-3.2.1 中给出了预期的行为,而在 R-3.1.2 中却没有。

根据@BondedDust 的评论进行编辑

建议的rapply(list(test), eval, envir = fenv) 在两个版本中都返回10,但在R-3.1.2 中的fenv 中不存储x。但是,建议的代码会根据需要返回 10 并将 x 存储在 R-3.2.1 中的 fenv 中。

@BondedDust 的原始建议:rapply(list(test), evalq, envir = fenv) 在 R-3.2.1 中给出了与原始问题中上述代码相同的错误。

我仍然希望找到一个解决方案,在新旧版本的 R 中将 x 变量存储在 fenv 中。

编辑以显示复杂性

我必须使用bquote,因为我正在从另一个函数生成表达式。这允许我创建对 data.table 对象的复杂调用,而无需将 data.table 对象发送到函数。在函数中,我可以调用一个方法,然后创建 data.table 表达式并将其应用于 data.table 对象,而无需将 data.table 发送到其他函数。我试图简化以下问题:

fenv <- environment()
func_list <- list(f1 = function(val) {e1 <- bquote(x <- .(val)); list(e1)})
test <- func_list[["f1"]](10)
rapply(test, evalq, envir = fenv)

rapply 是必需的,因为“func_list”中有返回表达式列表的函数,不一定像上面的示例中只有一个。我最终得到的是由bquote 生成的嵌套表达式列表,我需要在给定环境中对其进行评估,以便将结果对象(或对 data.table 的更改)存储在给定环境中。

我在以前版本的 R 中也有此功能,我正在尝试找出行为发生变化的原因以及如何纠正代码以使其在新旧版本的 R 中均有效。

【问题讨论】:

  • 这里的预期行为是什么?您是否尝试在 fenv 环境中定义 x 值?
  • @MrFlick 是的,很抱歉造成混乱。我正在使用与示例类似的代码来修改函数中的 data.tables,这样我就不必制作任何不必要的副本。
  • 我认为编辑不会创建您所说的应该是测试用例,即“表达式”的嵌套列表(特别是因为bquote 实际上返回的是“调用”而不是 R 的“表达式”)。对于经过测试的解决方案,我们仍然没有足够复杂的示例。在创建e1 时,还不清楚val 对象应该驻留在哪个环境中。
  • 我认为您最好提出一个与您正在尝试做的事情更密切相关的问题,而不是您当前使用的确切实现。我怀疑bquote()rapply() 是这里最好的工具。

标签: r


【解决方案1】:

typeof 函数不再返回“列表”,而是返回“测试”对象的“语言”。明显的解决方法是:

  rapply(list(test), evalq, envir = fenv)
[1] 10

在 R 3.1.2 中有效,但需要在 R 3.2.1 RC 中使用它

 rapply(list(test), eval, envir = fenv)
[1] 10    

我还查看了news() 以查看是否可能已宣布其中任何内容,并且找不到与typeofrapplyevalq 中的更改相关的任何内容。

编辑:尝试将quoteexpression 作为创建“测试”对象的函数。使用 expression-vector 在 3.1.2 和 3.2.1RC 上都获得了预期的结果

test <- expression( x <- 10 )
nenv <- new.env()
ls(envir=nenv)
#character(0)
 rapply(list(test), eval, envir = nenv)
#[1] 10
 ls(envir=nenv)
#[1] "x"
 nenv$x
#[1] 10

【讨论】:

  • 非常感谢您一直以来的帮助。不幸的是,我必须使用bquote,因为我是根据变量生成表达式。
  • 如果您需要“持续帮助”,请发布一个实际匹配问题复杂性的问题示例。
  • 我只是想感谢您已经完成的所有工作。我对问题添加了编辑。如果我不清楚,请告诉我。
猜你喜欢
  • 2018-06-11
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 2014-03-20
  • 1970-01-01
  • 1970-01-01
  • 2018-08-04
相关资源
最近更新 更多