expr 和 exprs 的类在 R 中的 rlang 中是不同的!为什么?



我不确定这里是否问过这个问题,但我在这里很困惑。我正在阅读哈德利·威克姆(Hadley Wickham(的这本名为Advanced R的精彩书。

这里有一个叫做cement的函数,我已经稍微修改了一下并试图理解它。

library(rlang)
cement1 <- function(x) {
dots <- expr(x)
print(class(dots))
#paste(expr_name(x))
}
cement2 <- function(y,z) {
dots <- exprs(y,z)
print(class(dots))
#paste(purrr::map(dots, expr_name), collapse = " ")
}

在没有任何参数的情况下运行上述cement1将点类作为"名称"返回我。

但是,当我使用附加参数运行cement2函数时,类返回"列表",{简单地放置类(expr(x(( 返回"名称",而类(exprs(x(( 返回"列表"}。

我不明白为什么它会打印exprexprs返回的不同类。我认为我知道的唯一区别是,一个处理一个参数,另一个处理多个参数,但我可能是错的,我可能错过了一些细节。

原始问题:所以,当我运行函数时,这一切都是通过删除代码中cement1cement2的注释部分分别运行这两个函数开始的 以下是它们返回的输出:

cement1(Hello) #Returns , Error in type_of(.x) : object 'Hello' not found 
cement2(Hello) #Works very well and returns, [1] "y z"

所以我试图找到cement1失败的原因,然后打印他们的类,这时我意识到,exprexprs返回不同的类。

我的问题是

1(它们是设计使然,如果是,那为什么?或者,我正在犯一些可怕的错误,我目前无法看到。

2(如果不是,cement1不能工作,正确的方法是什么?

很抱歉句子太长,我的第一语言不是英语,因此如果有什么愚蠢的地方,请告诉我我会纠正它。我希望这不是重复的,我试图找到答案,但我自己找不到。

感谢您的任何帮助。

R 版本:3.4.2rlang: 0.2.0

1( 是的,exprexprs的返回值因设计而异。从?expr帮助页面:

enexpr(( 和 expr(( 捕获单个原始表达式。

enexprs(( 和 exprs(( 捕获原始表达式的列表,包括包含在...中的表达式。

2(expr_name()期望引用的表达式,例如expr()产生的内容。因此,您需要修改cement1以在dots上调用expr_name(),而不是x。您还可以删除paste,因为您没有连接任何内容。

cement1 <- function(x) {
dots <- expr(x)
# print(class(dots))      ## Commented out for clarity
expr_name(dots)           ## The input to expr_name is now effectively expr(x)
}
cement1( Hello )
# "x"

你的函数基本上cement2exprs()返回的列表的每个元素上调用expr_name(),然后将结果连接成一个字符串。

2a( 现在我们让您的cement1正常工作,我们可以进一步改进它。目前,该函数不使用其输入参数xexpr()只是捕获未求值的表达式,并且无论您将参数命名为什么,此表达式都将始终x

cement1.1 <- function( completelyIgnoredName ) {
dots <- expr(x)
expr_name(dots)
}
cement1.1( Hello )
# "x"

但是,如果将expr()替换为enexpr(),该函数将替换提供的表达式作为函数的参数并捕获表达式:

cement1.2 <- function(x) {
dots <- enexpr(x)
expr_name(dots)
}
cement1.2( Hello )
# "Hello"

相关内容

  • 没有找到相关文章

最新更新