gettypes = function(x) {paramx = substitute(x); print(typeof(paramx)); print(class(paramx)); print(mode(paramx))}
gettypes(expression(sin(x+y)))
# [1] "language"
# [1] "call"
# [1] "call"
gettypes(quote(sin(x+y)))
# [1] "language"
# [1] "call"
# [1] "call"
expression(sin(x+y)) == quote(sin(x+y))
不允许比较
expression(sin(x + y)) == quote(sin(x + y))
中的错误: 表达式
identical(expression(sin(x+y)), quote(sin(x+y)))
# [1] FALSE
x = 1
y = 2
eval(expression(sin(x+y)))
# [1] 0.14112
eval(quote(sin(x+y)))
# [1] 0.14112
他们看起来几乎一样。
答案 0 :(得分:15)
expression
将其参数作为未评估表达式的向量返回。quote
将其参数作为未评估的表达式返回。试试这个:
(e1 <- quote(sin(x+y)))
# sin(x + y)
(e2 <- expression(sin(x+y)))
# expression(sin(x + y))
str(e1)
# language sin(x + y)
str(e2)
# expression(sin(x + y))
str(e2[[1]])
# language sin(x + y)
all.equal(e1, e2)
# [1] "Modes of target, current: call, expression" "target, current do not match when deparsed"
all.equal(e1, e2[[1]])
# [1] TRUE
另一个例子:
e2 = expression(sin(x+y), x+y)
e2
# expression(sin(x + y), x + y)
e2[1]
# expression(sin(x + y))
e2[2]
# expression(x + y)
答案 1 :(得分:0)
@kohske已经很好地回答了,但要敲定一个表达式实际上只是一个未评估表达式的列表,例如用引号返回的class
表达式:
x <- list(quote(2*3),quote(4*5))
class(x) <- "expression"
identical(x, expression(2*3, 4*5))
# [1] TRUE
expression
的模式不是"list"
,而是"expression"
,而不像data.frame
那样:
e <- expression(2*3, 4*5)
class(e)
# [1] "expression"
mode(e)
# [1] "expression"
class(unclass(e))
# [1] "expression"
is.list(e)
# [1] FALSE
class(iris)
# [1] "data.frame"
mode(iris)
# [1] "list"
class(unclass(iris))
# [1] "list"
is.list(iris)
# [1] TRUE
现在,不同的类可能意味着非常不同的方法,但是实际上至少在基数R中,它们并不多:
methods(class="expression")
# [1] coerce Ops
methods(class="list")
# [1] all.equal as.data.frame coerce Ops relist type.convert within
因此,将表达式视为未求值表达式的列表似乎相当安全,例如,当尝试使用表达式时(如我们将要使用的列表)出现问题时,as.list
将非常安全。 :
with(expression(a=2*3, 4*5),a)
# Error in eval(substitute(expr), data, enclos = parent.frame()) :
# invalid 'envir' argument of type 'expression'
with(as.list(expression(a=2*3, 4*5)),a)
# 2 * 3