How to write c () function for custom class S3 in R

I am writing an S3 class in R, which is an integer with attributes attached to it. If x1 and x2 are objects of this class (call it "myclass"), I would like c (x1, x2) to return a vector of myclass objects with the original class definition and attributes intact. However, the documented behavior of c () is to remove the attributes, so it seems to me that I need to write my own c.myclass () method. My question is: how can I do this?

Example problem:

myclass <- function(x, n) structure(x, class="myclass", n=n) x1 <- myclass(1, 5) x2 <- myclass(2, 6) c(x1, x2) [1] 1 2 

Here, the result is just a vector of elements of class numeric, and the original attribute n has disappeared.

Looking at the code for various packages, I sometimes see code similar to the following, in which we need to save the class attribute, but no more:

 c.myclass <- function(..., recursive = F) { structure(c(unlist(lapply(list(...), unclass))), class="myclass") } 

Unfortunately, I can't get this to work either. The result of calling c.myclass (x1, x2) is a vector in which the vector itself has a class of "myclass", but where each element in the vector has a class of numeric; I really want every element in the vector to have a class of "myclass". In practice, I will also need to update this method to save other attributes (for example, the attribute "n" in myclass).

+6
r r-s3
source share
2 answers

This works, but I assume that you conclude that each vector element has a numeric number, because you are doing something like this:

 foo <- c(x1, x2) class(foo[1]) class(foo[2]) 

If this is the case and you want the selected items to retain the myclass attribute, you need to write a subset method of "[.myclass" to save the attributes.

+4
source share

Here is an example that does (I think) what you want using specific methods for c and [ :

 c.myclass <- function(..., recursive = FALSE) { dots <- list(...) ns <- sapply(dots, attr, which = "n") classes <- rep("myclass", length(dots)) res <- structure(unlist(dots, recursive = FALSE), class = classes) attr(res, "n") <- ns res } `[.myclass` <- function (x, i) { y <- unclass(x)[i] ns <- attr(x, "n")[i] class(y) <- "myclass" attr(y, "n") <- ns y } myclass <- function(x, n) structure(x, class = "myclass", n = n) x1 <- myclass(1, 5) x2 <- myclass(2, 6) c(x1, x2) c(x1, x2)[2] 

But this means that we need to control the processing of settings and subsets of additional attributes to store n . This is really just a numeric vector with an attribute for writing n .

Perhaps it would be more natural to work with a list common to all vectors. A bit that is more involved, and perhaps higher in your case, is enough?

+7
source share

All Articles