substitute() in S4

最近在写一个S4的class,想实现一个很简单的功能,那就是在针对这个class定义的函数中,可以获取输入的变量的变量名。比如

setGeneric("A", function(x, ...) standardGeneric("A"))
## [1] "A"
setMethod("A", signature("numeric"), 
function(x, ...) deparse(substitute(x)))
## [1] "A"
A(iris[,1])
## [1] "iris[, 1]"

但是当我增加一个参数,也就是当参数与一开始的设定不一致的时候,它就不能正常工作了。

setMethod("A", signature("numeric"),
function(x, y, ...) deparse(substitute(x)))
## [1] "A"
A(iris[,1])
## [1] "x"

为什么呢?我在http://stackoverflow.com/questions/13517720/substitute-in-s4找到了答案。 我们看一眼现在的A method有什么吧。

showMethods(A, includeDef=TRUE)
## Function: A (package .GlobalEnv)
## x="numeric"
## function (x, ...) 
## {
##     .local <- function (x, y, ...) 
##     deparse(substitute(x))
##     .local(x, ...)
## }

也就是说,当你给定的参数与一开始设计的standardGeneric参数不一致的时候,系统自动对A的function重包装了一次。当我们调用substitute的时候,它的environment已经是.local函数了。所以我们在错误的假设参数的环境。

既然是这样,那么就有解决办法了。

setMethod("A", signature("numeric"), 
function(x, y, ...) deparse(substitute(x, env=parent.frame())))
## [1] "A"
A(iris[,1])
## [1] "iris[, 1]"

Leave a Reply

  

  

  

%d 博主赞过: