`quote()` 和 `call()`:如何区分两个输出?

问题描述 投票:0回答:1

动机

我正在编写一个将调用作为输入的函数。然而我注意到 R 有两种不同的方式来创建调用,要么通过

call()
要么通过
quote()
。根据调用的函数,我的代码的行为有所不同,因此我想将两种类型的对象转换为单一对象,以避免扩展代码。

示例

考虑以下两个对象:

call_obj <- "rnorm(5)" |> call()
quote_obj <- rnorm(5) |> quote()

请注意,它们在控制台中打印不同的输出:

> call_obj
`mean()`()
> quote_obj
mean()

但是,它们具有相同的 classtypemode

> class(call_obj)
[1] "call"
> class(quote_obj)
[1] "call"
> mode(call_obj)
[1] "call"
> mode(quote_obj)
[1] "call"
> typeof(call_obj)
[1] "language"
> typeof(quote_obj)
[1] "language"
> str(call_obj)
 language `mean()`()
> str(quote_obj)
 language mean()

区分

我已经能够通过两种方法区分这两个物体。

最简单的就是通过

length()
。由于
call_obj
似乎总是返回 1 的长度,而
quote_obj
返回的长度等于调用中显式参数的数量 + 1。但是,如果该函数不能接受显式参数并运行,则这种方法会失败仅使用默认值,例如
mean()
。有没有更强大、简洁的替代方案?尝试了使用
grepl
和反引号的替代方案,但即使它们在
str()
打印输出中可见,它们似乎也没有检测到它们。

复杂的是利用

call_obj
可以通过
转换为
quote_obj

这一事实
> all.equal(call_obj[[1]] |> as.character() |> str2lang(), quote_obj)
[1] TRUE

而应用于已经是引用的对象的相同函数将返回

FALSE
:

> all.equal(quote_obj[[1]] |> as.character() |> str2lang(), quote_obj)
[1] "Modes of target, current: name, call"
[2] "target is a subset of current"   

额外问题:将

quote_obj
转换为等于
call_obj
的简洁方法是什么?


如果这里有一些非常不

R
的方法,并且还有更惯用的方法,请评论!

r expression method-call
1个回答
0
投票

您的示例

call_obj <- "rnorm(5)" |> call()
生成对名为
"rnorm(5)"
且不带参数的函数的调用,而不是对带有参数
"rnorm"
5
的调用。 如果这就是您真正想要的,那么将
as.character(call_obj[[1]]))
as.character(quote_obj[[1]])
进行比较就会显示出差异。

如果您确实希望两者都调用

rnorm(5)
,那么您需要使用

call_obj <- "rnorm" |> call(5)

结果将与您在

quote_obj
中得到的结果相同。

© www.soinside.com 2019 - 2024. All rights reserved.