rlang包中sym()和parse_expr()有什么区别?

时间:2018-05-03 15:34:22

标签: r string evaluation rlang

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

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

然而,

df.query(
    '(@start_date <= index < @end_date) & '
    '@np.is_busday(index, holidays=@dd.all_holidays)'
)

我的一些问题是sym()和parse_expr()之间有什么区别? 一个人做了什么,另一个不能?为什么ex5显然与ex6相似但相同(ex5,ex6)返回FALSE?

2 个答案:

答案 0 :(得分:7)

引用我对此question的回答:

符号是一种引用R对象的方式,基本上是&#34; name&#34;一个对象。因此,sym类似于基础R中的as.nameparse_expr另一方面将某些文本转换为R表达式。这类似于基础R中的parse

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

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

对于您的第一个示例,a可以是引用对象和表达式的名称,因此将其转换为symparse_expr实际上意味着相同的事情。

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

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

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

此处,syma - b转换为对象的名称/符号,因此后面围绕a - b,而parse_expr转把它变成了预期的表达。

答案 1 :(得分:3)

要扩充上一个答案,请注意reduceex5实际上并不相同。

ex6