Using the call function of NextMethod () in an access function in R

This is due to the following message Problems passing arguments by calling NextMethod () in R

I am writing accessors for the two classes S4, "foo" and "bar". "bar" is inherited from foo and applies only to a few slots. Instead of writing a full accessor function for objects of class "bar", I want to pass arguments to the call of NextMethod () when accessing a slot that is inherited by "foo". My code is as follows:

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 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 the object 'f' of class 'foo' correctly returns:

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

If I try to access the slot "distance" of the object "b" of the class "bar", then the accessor will also correctly return:

 > b["distance"] [1] 5 

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

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

The following error message appears:

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

I read the recommendations from this post Problems with passing arguments by calling NextMethod () to R , but I can’t define a common one for '[' and trying to pass arguments explicitly to call NextMethod () also failed.

Of course I'm doing something wrong! I have read several resources by inheritance and cannot determine the problem, and I hope that you people can guide me in the right direction.

thanks

Max

+6
source share
1 answer

Your methods do not take into account 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 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 
+4
source

Source: https://habr.com/ru/post/972621/


All Articles