class 的 expr 和 exprs 在 R 的 rlang 中是不同的!为什么?
class of expr and exprs are different in rlang in R ! Why?
我不确定这里是否有人问过这个问题,但我在这里很困惑。我正在阅读 Hadley Wickham 的这本很棒的书 Advanced R,来自 here。
这里描述了一个名为 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
没有任何参数 return 我是 class 的点作为 "name".
然而,当我运行带有附加参数的cement2
函数时,classreturns "list",{简单地说class(expr(x)) returns "name" 而 class(exprs(x)) returns "list"}。
我不明白为什么它打印的 class return 由 expr
和 exprs
编辑。我认为我知道的唯一区别是,一个处理一个参数,另一个处理多个参数,但我可能错了,我可能错过了一些细节。
原始问题:因此,这一切都是从 运行 通过删除代码中 cement1
和cement2
,当我 运行 函数时,下面是它们 returned 的输出:
cement1(Hello) #Returns , Error in type_of(.x) : object 'Hello' not found
cement2(Hello) #Works very well and returns, [1] "y z"
所以我试图找出 cement1
失败的原因,然后打印出他们的 classes 然后我意识到,expr
和 exprs
return 不同 classes.
我的问题是:
1) 它们是设计使然吗?如果是,那为什么?或者,我正在犯一些我目前看不到的可怕错误。
2) 如果不行,cement1
是不是不行,正确的方法是什么?
很抱歉句子太长,我的第一语言不是英语,因此如果有任何愚蠢的地方,请告诉我我会改正。我希望这不是重复的,我试图找到答案但我自己找不到。
感谢您的帮助。
R 版本: 3.4.2
rlang: 0.2.0
1) 是的,expr
和 exprs
的 return 值因设计而异。来自 ?expr
帮助页面:
enexpr() and expr() capture a single raw expression.
enexprs() and exprs() capture a list of raw expressions including expressions contained in ...
.
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"
你的函数 cement2
基本上调用 expr_name()
由 exprs()
编辑的列表 return 的每个元素,然后将结果连接成一个字符串。
2a) 现在我们让您的 cement1
正常工作,我们可以进一步改进它。目前,该函数不使用其输入参数 x
。 expr()
简单地捕获未计算的表达式,这个表达式将永远是 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"
我不确定这里是否有人问过这个问题,但我在这里很困惑。我正在阅读 Hadley Wickham 的这本很棒的书 Advanced R,来自 here。
这里描述了一个名为 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
没有任何参数 return 我是 class 的点作为 "name".
然而,当我运行带有附加参数的cement2
函数时,classreturns "list",{简单地说class(expr(x)) returns "name" 而 class(exprs(x)) returns "list"}。
我不明白为什么它打印的 class return 由 expr
和 exprs
编辑。我认为我知道的唯一区别是,一个处理一个参数,另一个处理多个参数,但我可能错了,我可能错过了一些细节。
原始问题:因此,这一切都是从 运行 通过删除代码中 cement1
和cement2
,当我 运行 函数时,下面是它们 returned 的输出:
cement1(Hello) #Returns , Error in type_of(.x) : object 'Hello' not found
cement2(Hello) #Works very well and returns, [1] "y z"
所以我试图找出 cement1
失败的原因,然后打印出他们的 classes 然后我意识到,expr
和 exprs
return 不同 classes.
我的问题是:
1) 它们是设计使然吗?如果是,那为什么?或者,我正在犯一些我目前看不到的可怕错误。
2) 如果不行,cement1
是不是不行,正确的方法是什么?
很抱歉句子太长,我的第一语言不是英语,因此如果有任何愚蠢的地方,请告诉我我会改正。我希望这不是重复的,我试图找到答案但我自己找不到。
感谢您的帮助。
R 版本: 3.4.2 rlang: 0.2.0
1) 是的,expr
和 exprs
的 return 值因设计而异。来自 ?expr
帮助页面:
enexpr() and expr() capture a single raw expression.
enexprs() and exprs() capture a list of raw expressions including expressions contained in
...
.
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"
你的函数 cement2
基本上调用 expr_name()
由 exprs()
编辑的列表 return 的每个元素,然后将结果连接成一个字符串。
2a) 现在我们让您的 cement1
正常工作,我们可以进一步改进它。目前,该函数不使用其输入参数 x
。 expr()
简单地捕获未计算的表达式,这个表达式将永远是 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"