R中的一个bquote拼接

时间:2014-02-20 00:23:37

标签: r

假设我正在使用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),但这不起作用。还有其他想法吗?重申一下,我不想诉诸字符串操作。

3 个答案:

答案 0 :(得分:5)

这是一个有趣的问题。在玩了一些东西之后,这就是我能为你的特定例子想出来的。

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

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

答案 1 :(得分:2)

你需要意识到R表达式不会与他们的打印方法可能让你相信的中缀顺序一起存储:

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

而语言对象的打印方法可能会让您认为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

答案 2 :(得分:2)

在要作为R 4.0.0发布的R devel版本中,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的方式引起的。

请遵循其他答案以寻求可行的解决方案。