Using callNextMethod() within accessor function in R

旧巷老猫 提交于 2019-12-21 12:22:36

问题


This is related to the following post Problems passing arguments with callNextMethod() in R

I am writing accessors for two S4 classes, 'foo' and 'bar'. 'bar' inherits from foo and is extended only by a few slots. Instead of writing a full accessor function for objects of class 'bar' I want to pass the arguments to callNextMethod() when accessing a slot that is inherited by 'foo'. My code looks like this:

foo <- setClass("foo", representation(x = "numeric", y = "numeric"))
bar <- setClass("bar", representation(distance = "numeric"), contains = "foo")

setMethod("[", "bar", function(x, i, j, drop) {
  if (i == "distance") {
    return(x@distance)
    } else {
      callNextMethod()
    }
}
)

setMethod("[", "foo", function(x, i, j, drop) {
  if (i == "x") {
    return(x@x)
    } else {
      if (i == "y") {
        return(x@y)
      }
    }
}
)

Now let's try this:

f <- new("foo", x = 1, y = 2)
b <- new("bar", x = 3, y = 4, distance = 5)
f["x"]
f["y"]

The accessor for object 'f' of class 'foo' properly returns:

> f["x"]
[1] 1
> f["y"]
[1] 2

If I try to access the slot 'distance' of the object 'b' of class 'bar' the accessor also properly returns:

> b["distance"]
[1] 5

The problem occurs when I try to access any of the slots of the object 'b' of class 'bar' which are inherited from 'foo'. If I try:

b["x"]
b["y"]

I get the following error message:

Error in callNextMethod() : bad object found as method (class “function”)

I have read the recommendations from this post Problems passing arguments with callNextMethod() in R but I cannot define a generic for '[' and trying to pass the arguments explicitly to callNextMethod() also failed.

Surely I am doing something wrong! I have read several resources on inheritances and cannot identify the problem and I hope you folks will be able to guide me towards the right direction.

Thanks

Max


回答1:


Your methods both leave out one of the five formal arguments required by any [ method, namely the ellipsis (...).

args(getGeneric("["))
# function (x, i, j, ..., drop = TRUE) 
# NULL

Including it as a formal in both method definitions solves your problem:

setMethod("[", "bar", function(x, i, j, ..., drop) {
  if (i == "distance") {
    return(x@distance)
    } else {
      callNextMethod()
    }
}
)

setMethod("[", "foo", function(x, i, j, ..., drop) {
  if (i == "x") {
    return(x@x)
    } else {
      if (i == "y") {
        return(x@y)
      }
    }
}
)

b["distance"]
# [1] 5
b["x"]
# [1] 3
b["y"]
# [1] 4


来源:https://stackoverflow.com/questions/24875284/using-callnextmethod-within-accessor-function-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!