首页 > 解决方案 > rlang 包中的 sym() 和 parse_expr() 有什么区别?

问题描述

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

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

他们都回来了

a

identical(ex1, ex2)
[1] TRUE

假设现在我需要一个 quosure:

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?

标签: rstringevaluationrlang

解决方案


参考我对这个问题的回答:

符号是引用 R 对象的一种方式,基本上是对象的“名称”。所以sym类似于as.name在基础 Rparse_expr中。另一方面,将一些文本转换为 R 表达式。这类似于parse在基础 R 中。

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

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

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

但是,对于您的最后一个示例,a - b它实际上是一个表达式(除非您有一个奇怪命名的 R 对象a - b)。通过打印以下内容,您将看到将symvs用于旨在成为表达式而不是 R 对象的parse_exprR 代码会产生两种不同的结果:

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

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

在这里,sym变成a - b一个对象的名称/符号,因此后面打勾a - b,同时parse_expr按预期将它变成一个表达式。


推荐阅读