R match.call() 用于 S4 方法
R match.call() for S4 methods
我目前正在为 S4 class 编写一个方法,我想像调用函数一样调用该方法并使用 match.call()。
这是我正在做的最简单的例子:
setClass(
Class = "AClass",
representation = representation(
name = "character"
)
)
setGeneric("meth1", function(object, ...) {
standardGeneric("meth1")
})
setMethod(
f = "meth1",
signature = "AClass",
definition = function(object, method, ..., warnings = TRUE) {
# ...
print(match.call())
return(NA)
})
根据这个定义,我看到了:
> meth1(new("AClass"), method = "MClust")
.local(object = object, method = "MClust")
[1] NA
> meth1(new("AClass"), method = Mclust)
.local(object = object, method = ..1)
[1] NA
问题是:
为什么将函数赋值给参数'method'时,从match.call()
得到的参数内容是..1
而不是"Mclust"
?
为什么从 match.call()
得到的“函数名”是 .local
而不是 meth1
?
如何从函数中的变量 method
中获取 "Mclust"
?
当涉及 ...
和多层函数调用时,match.call
的工作方式存在一些问题。这与 match.call
通过词法堆栈搜索以找到要替换的 ...
而不是动态堆栈有关。我写了一个包来尝试纠正这些问题:
devtools::install_github("brodieg/matchcall") # <-- the package in question
library(matchcall)
setMethod(
f = "meth1",
signature = "AClass",
definition = function(object, method, ..., warnings = TRUE) {
# ...
print(match.call())
print(match_call())
print(match_call(2))
return(NA)
})
meth1(new("AClass"), method = Mclust)
产生:
.local(object = object, method = ..1) # match.call
.local(object = object, method = Mclust) # match_call(), my package
meth1(object = new("AClass"), method = Mclust) # match_call(2), my package offset
[1] NA
所以,要回答问题 2,你得到 .local
的原因是因为有一系列调用最终导致对你定义的函数进行评估,并且 S4 将该函数存储为 .local
.
第1题的答案比较复杂,具体可以看vignette included with my package. Note that internally in C code ...
arguments have names ..1
, ..2
, etc (from R Internals):
Recall that the evaluation frame for a function initially contains the name=value pairs from the matched call, and hence this will be true for ... as well. The value of ... is a (special) pairlist whose elements are referred to by the special symbols ..1, ..2, … which have the DDVAL bit set: when one of these is encountered it is looked up (via ddfindVar) in the value of the ... symbol in the evaluation frame.
回复问题3,没看懂。您是否希望能够放入一个未加引号的变量作为参数 "method",然后将其解释为一个字符?
请注意,该软件包目前仅在 github 上提供,但您可以使用 sys.calls
来满足您的需要。例如,如果我们在您的方法中 运行 print(sys.calls())
,我们得到:
[[1]]
meth1(new("AClass"), method = Mclust)
[[2]]
meth1(new("AClass"), method = Mclust)
[[3]]
.local(object, ...)
您可以直接使用它,但这只有在您在调用中完全指定参数名称的情况下才能很好地工作(即,如果有人这样做 meth1(x, "blah")
,您将不会得到 method=
它的一部分在 sys.calls
中。如果你有多个参数或部分指定的参数(例如 meth=X
),那么你将不得不做更多的工作来匹配东西(这正是 match_call
确实)。
我目前正在为 S4 class 编写一个方法,我想像调用函数一样调用该方法并使用 match.call()。
这是我正在做的最简单的例子:
setClass(
Class = "AClass",
representation = representation(
name = "character"
)
)
setGeneric("meth1", function(object, ...) {
standardGeneric("meth1")
})
setMethod(
f = "meth1",
signature = "AClass",
definition = function(object, method, ..., warnings = TRUE) {
# ...
print(match.call())
return(NA)
})
根据这个定义,我看到了:
> meth1(new("AClass"), method = "MClust")
.local(object = object, method = "MClust")
[1] NA
> meth1(new("AClass"), method = Mclust)
.local(object = object, method = ..1)
[1] NA
问题是:
为什么将函数赋值给参数'method'时,从
match.call()
得到的参数内容是..1
而不是"Mclust"
?为什么从
match.call()
得到的“函数名”是.local
而不是meth1
?如何从函数中的变量
method
中获取"Mclust"
?
当涉及 ...
和多层函数调用时,match.call
的工作方式存在一些问题。这与 match.call
通过词法堆栈搜索以找到要替换的 ...
而不是动态堆栈有关。我写了一个包来尝试纠正这些问题:
devtools::install_github("brodieg/matchcall") # <-- the package in question
library(matchcall)
setMethod(
f = "meth1",
signature = "AClass",
definition = function(object, method, ..., warnings = TRUE) {
# ...
print(match.call())
print(match_call())
print(match_call(2))
return(NA)
})
meth1(new("AClass"), method = Mclust)
产生:
.local(object = object, method = ..1) # match.call
.local(object = object, method = Mclust) # match_call(), my package
meth1(object = new("AClass"), method = Mclust) # match_call(2), my package offset
[1] NA
所以,要回答问题 2,你得到 .local
的原因是因为有一系列调用最终导致对你定义的函数进行评估,并且 S4 将该函数存储为 .local
.
第1题的答案比较复杂,具体可以看vignette included with my package. Note that internally in C code ...
arguments have names ..1
, ..2
, etc (from R Internals):
Recall that the evaluation frame for a function initially contains the name=value pairs from the matched call, and hence this will be true for ... as well. The value of ... is a (special) pairlist whose elements are referred to by the special symbols ..1, ..2, … which have the DDVAL bit set: when one of these is encountered it is looked up (via ddfindVar) in the value of the ... symbol in the evaluation frame.
回复问题3,没看懂。您是否希望能够放入一个未加引号的变量作为参数 "method",然后将其解释为一个字符?
请注意,该软件包目前仅在 github 上提供,但您可以使用 sys.calls
来满足您的需要。例如,如果我们在您的方法中 运行 print(sys.calls())
,我们得到:
[[1]]
meth1(new("AClass"), method = Mclust)
[[2]]
meth1(new("AClass"), method = Mclust)
[[3]]
.local(object, ...)
您可以直接使用它,但这只有在您在调用中完全指定参数名称的情况下才能很好地工作(即,如果有人这样做 meth1(x, "blah")
,您将不会得到 method=
它的一部分在 sys.calls
中。如果你有多个参数或部分指定的参数(例如 meth=X
),那么你将不得不做更多的工作来匹配东西(这正是 match_call
确实)。