rlang包中的sym()和parse_expr()有什么区别? [英] What is the difference between sym() and parse_expr() in the rlang package?

查看:214
本文介绍了rlang包中的sym()和parse_expr()有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用rlang包,我想知道sym()parse_expr()之间的区别是什么.例如,考虑以下表达式:

ex1 = sym('a')
ex2 = parse_expr('a')

他们俩都返回

a

identical(ex1, ex2)
[1] TRUE

假设现在我需要一个担保:

ex3 = quo(!!sym('a'))
ex4 = quo(!!parse_expr('a'))

在两种情况下,结果均为:

<quosure>
expr: ^a
env:  global

identical(ex3, ex4)
[1] TRUE

但是,由于某些原因,下面的两个不相同.

ex5 = quo(!!sym('a - b'))
ex6 = quo(!!parse_expr('a - b'))

显然,它们都是相同的,因为两者都返回:

<quosure>
expr: ^a - b
env:  global

但是

identical(ex5, ex6)
[1] FALSE

所以,我的问题是,sym()parse_expr()之间有什么区别? 另一个不能做什么?为什么ex5显然与ex6类似,但是identical(ex5, ex6)返回FALSE?

解决方案

参考我对此sym与基本R中的as.name相似.另一方面,parse_expr将某些文本转换为R表达式.这类似于基R中的parse.

表达式可以是任何R代码,而不仅仅是引用R对象的代码.因此,您可以解析引用R对象的代码,但是如果代码引用的对象不存在,则不能将某些随机代码转换为sym.

通常,当字符串引用对象时,将使用sym(尽管parse_expr也可以使用),而当尝试解析任何其他R代码以进行进一步评估时,将使用parse_expr.

>

对于您的第一个示例,a既可以是引用对象的名称又可以是表达式,因此将其转换为symparse_expr实际上意味着相同的意思.实际上,如第一个示例所示,R会在可能的情况下将表达式隐式转换为sym.

但是对于最后一个示例,a - b实际上是要用作表达式(除非您有一个奇怪地命名为a - b的R对象).通过打印以下内容,您将看到对要用作表达式而非R对象的R代码使用sym vs parse_expr会产生两个不同的结果:

> quo(!!sym('a - b'))
<quosure: global>
~`a - b`

> quo(!!parse_expr('a-b'))
<quosure: global>
~a - b

在这里,syma - b转换为对象的 name/symbol ,因此a - b周围出现了滴答声,而parse_expr则将其转换为预期的表达式. /p>

Using the rlang package, I wonder what is the difference between sym() and parse_expr(). Consider for example the following expressions:

ex1 = sym('a')
ex2 = parse_expr('a')

They both return

a

identical(ex1, ex2)
[1] TRUE

Suppose now I need a quosure:

ex3 = quo(!!sym('a'))
ex4 = quo(!!parse_expr('a'))

In both case, the result is:

<quosure>
expr: ^a
env:  global

identical(ex3, ex4)
[1] TRUE

However, the two following are not the same for some reasons.

ex5 = quo(!!sym('a - b'))
ex6 = quo(!!parse_expr('a - b'))

Apparently they are identical as both return:

<quosure>
expr: ^a - b
env:  global

Yet,

identical(ex5, ex6)
[1] FALSE

So, my question is, what are the differences between sym() and parse_expr()? What does one do that the other cannot? And why is ex5 apparently similar to ex6, but identical(ex5, ex6) returns FALSE?

解决方案

Referencing my answer to this question:

A symbol is a way to refer to an R object, basically the "name" of an object. So sym is similar to as.name in base R. parse_expr on the other hand transforms some text into R expressions. This is similar to parse in base R.

Expressions can be any R code, not just code that references R objects. So you can parse the code that references an R object, but you can't turn some random code into sym if the object that the code references does not exist.

In general, you will use sym when your string refers to an object (although parse_expr would also work), and use parse_expr when you are trying to parse any other R code for further evaluation.

For your first example, a can be both a name that references an object AND an expression, so turning it into either a sym or parse_expr would practically mean the same thing. In fact, R implicitly converts the expression to a sym when it can, as shown in your first example.

For your last example however, a - b is really intended to be an expression (unless you have an R object that is weirdly named a - b). By printing the following, you will see that using sym vs parse_expr for R code that is intended to be an expression, not an R object produces two different results:

> quo(!!sym('a - b'))
<quosure: global>
~`a - b`

> quo(!!parse_expr('a-b'))
<quosure: global>
~a - b

Here, sym turns a - b into a name/symbol of an object, hence the back ticks around a - b, while parse_expr turns it into an expression as expected.

这篇关于rlang包中的sym()和parse_expr()有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆