bounty还有4天到期。此问题的答案有资格获得+50声望奖励。rez希望引起更多关注这个问题。
我有一个来自源代码的function
,它使用了几个输入,包括国家名称,并返回该国家的图表。函数的第一行定义了一个我无法理解的Country_name
对象。当我试图从函数中取出该部分并单独运行它时,它返回一个错误,而它在函数中工作正常。有人知道为什么会发生这种情况吗?Country_name的那行代码的目的是什么?
function(df, dfline, Country_name){
Country_name <- rlang::parse_expr(quo_name(enquo(Country_name)))
df %>%
filter(Country == Country_name ...
}
拉出第一行并单独运行它会返回一个错误:
parse_expr(quo_name(enquo('United States')))
### Error in `enquo()`:
### ! `arg` must be a symbol
3条答案
按热度按时间dsf9zpds1#
假设这是你的数据集:
你可以把你的自定义过滤器函数简单地写为:
但是,假设您希望能够省略
'Brazil'
周围的引号,并且仍然获得相同的输出。如果你没有修改,你会得到一个错误:R将
Brazil
理解为变量,并在全局环境中查找它。它找不到它,然后返回一个错误。如果Brazil
是一个变量,你可能会得到奇怪的结果:R看到
Brazil
的值为'Canada'
,将该值绑定到Country_name
,并在过滤器上使用该值。这不是你想要的您希望获得实际的单词
Brazil
,而不是它表示的值。这就是你提到的那条线的作用。我将在下面解释它是如何工作的。第一步是对R说“我不想让你评估你收到的参数,我只想让你保存它的文本”。也就是说,我们希望 * 延迟传递到
Country_name
的 * 表达式 * 的求值 *。这可以通过以下几种方式实现:substitute(Country_name)
在碱基R中,正如Nir Graham所指出的;substitute返回**(未求值)表达式**的解析树... - 替代的帮助页。
enquo(Country_name)
和rlang,就像你的函数一样。enquo()和enquos()化解函数参数。可以检查、修改已消除的表达式并将其注入到其他表达式中。-enquo的帮助页面。
enexpr(Country_name)
与rlang,也如Nir Graham所述;enexpr()和enexprs()类似于enquo()和enquos(),但返回裸表达式而不是quosures。-enexpr的帮助页面
所以它们都有非常相似的效果。最大的区别是
enquo
“返回quosures而不是裸表达式”。简单地说,quosures 是一个表达式,它也指向应该找到相关变量值的环境 *。我们不需要这样做(但这也不是问题),因为所讨论的表达式不会被求值,我们只需要它的文本。之后,我们只想得到那个被消隐的表达式的文本,可以用以下命令来实现:
as.character()
;deparse1()
;rlang::quo_name()
;rlang::expr_name()
.因此,这些选项与Nir Graham所做的类似:
所有产量:
注意,我们不需要删除
Brazil
变量,因为它没有被计算。c86crjj02#
它使用3个函数调用来完成2中可实现的功能,无论是在base中还是使用rlang。
oogrdqng3#
首先让我们构建一个最小的reprex
然后让我们使用boomer来打印中间输出:
我们看到:
enquo()
将输入捕获到quosure中quo_name()
将表达式提取为字符串parse_expr()
从字符串构建符号quote(a) == "a"
来检查它是如何工作的)。如果我们想更好地理解对象,我们可以在print参数中使用{constructive}。它将打印代码来重建对象,而不是打印对象。
创建于2023-06-02使用reprex v2.0.2
底线是,代码是臃肿的,也怪异和不安全,你不应该提供字符串作为变量只是为了备用双引号,你将如何提供“英国”?
正确的方法是将
Country_name
作为字符串提供,并具有:或者为了更加安全,如果
df
可能包含一个Country_name
列,该列将与参数冲突:或