【问题标题】:splice in a bquote in R在 R 中的 bquote 中拼接
【发布时间】:2014-03-20 16:11:31
【问题描述】:

假设我正在使用 R 的反引号运算符 bquote 构建表达式,并且我想在列表中的特定位置“拼接”(即,丢失列表的外括号)。

例如,我有表达式“5+4”,我想在它的开头添加一个“6-”,而不使用字符串操作(即,完全对符号结构进行操作) .

所以:

>   b = quote(5+4)
>   b
5 + 4
>   c = bquote(6-.(b))
>   c
6 - (5 + 4)
>   eval(c)
[1] -3

我希望返回“6-5+4”的评估,所以 5。

在普通的 lisp 中,反引号“`”运算符带有一个拼接运算符“,@”,可以做到这一点:

CL-USER> 
(setf b `(5 + 4))
(5 + 4)
CL-USER> 
(setf c `(6 - ,@b))
(6 - 5 + 4)
CL-USER> 
(setf c-non-spliced `(6 - ,b))
(6 - (5 + 4))
CL-USER> 

我尝试在 R 中使用 .@(b),但没有奏效。还有其他想法吗?重申一下,我不想诉诸字符串操作。

【问题讨论】:

  • 我认为从根本上讲,这都是“字符串操作”。

标签: r metaprogramming


【解决方案1】:

这是一个有趣的问题。在玩了一些东西之后,这就是我能为您的特定示例提出的全部内容。

> b <- quote(5 + 4)
> b[[2]] <-  bquote(6 - .(b[[2]]))
> b
6 - 5 + 4
> eval(b)
[1] 5

不幸的是,这可能很难概括,因为您必须考虑评估顺序等。

【讨论】:

    【解决方案2】:

    您需要意识到,R 表达式的存储顺序不是它们的 print 方法可能会让您相信的中缀顺序:

    > b = quote(5+4)
    >  b[[1]]
    `+`
    > b = quote(5+4)
    >  b[[2]]
    [1] 5
    > b = quote(5+4)
    >  b[[3]]
    [1] 4
    

    而语言对象的 print 方法可能会让您认为 6 -5 +4 的第二个参数是 6-5,....

    > b2 <- bquote(6 - 5 + 4)
    > b2[[1]]
    `+`
    > b2[[2]]
    6 - 5
    

    ....这也是一种错觉。它确实有一个列表结构。 (我原以为这是 Lisp 用户所期望的。)

    > b2[[3]]
    [1] 4
    > b2[[2]][[1]]
    `-`
    > b2[[2]][[2]]
    [1] 6
    > b2[[2]][[3]]
    [1] 5
    

    【讨论】:

    • 我确实意识到这是一个 AST,但这并不能真正直接解决问题。
    • 我同意它不能解决问题,但我认为定义问题的适当维度会有所帮助。无论如何,我不太相信这是真正的问题,所以我更希望看看“用例”是什么。
    • 这绝对暗示了一种实现.@的方法。我有点希望有一个有人知道的代码遍历库。
    • 不知道在哪里可以找到,甚至不知道什么是“代码遍历库”,但你看过bquote 的代码吗?
    • @IShouldBuyABoat 如果 bquote 具有拼接功能,这里有一个潜在的用例,刚刚发布在 SO:stackoverflow.com/a/22336062/822162
    【解决方案3】:

    在作为 R 4.0.0 发布的 R 开发版本中,bquote 中有一个新的拼接表达式功能。相关新闻来自https://cran.r-project.org/doc/manuals/r-devel/NEWS.html

    反引号函数 bquote() 有一个新参数 splice,可以将计算的值列表拼接到表达式中,例如 LISP 的反引号中的 ,@。

    还有来自https://stat.ethz.ch/R-manual/R-devel/library/base/html/bquote.html的手动示例

    exprs <- expression(x <- 1, y <- 2, x + y)
    bquote(function() {..(exprs)}, splice = TRUE)
    #function() {
    #    x <- 1
    #    y <- 2
    #    x + y
    #}
    

    不幸的是,它没有解决您的用例:

    e = quote(5 + 4)
    bquote(6 - ..(e), splice=TRUE)
    #6 - (5 + 4)
    

    删除括号并不容易,因为它需要旋转 AST。这是由 R 实现 AST 的方式引起的。

    请按照其他答案寻求可行的解决方案。

    【讨论】:

      猜你喜欢
      • 2015-12-29
      • 1970-01-01
      • 2018-06-11
      • 2015-10-03
      • 2014-12-13
      • 1970-01-01
      • 2021-03-02
      • 1970-01-01
      • 2021-11-17
      相关资源
      最近更新 更多