Reputation: 759
If I use a custom class, instantiate it, and add it to a matrix, can I control how the output looks?
For example, I have a class cell
I instantiate and add to a matrix. When I show
the matrix, it shows up as a questionmark. Can I control how this output looks?
setClass("cell", representation(a="character", b="character"))
setMethod("show", "cell",
function(object) print(paste(object@a,'|',object@b))
)
cell1<-
new("cell", a="hello", b="world")
mat1<-
matrix(c(cell1))
> print(cell1)
[1] "hello | world"
> print(mat1)
[,1]
[1,] ?
Upvotes: 1
Views: 60
Reputation: 52637
Unfortunately print
does not appear to dispatch on the sub-components of an object after an initial dispatch, which is terribly annoying but likely done for efficiency reasons. Here is a work around:
setMethod("as.character", "cell", function(x, ...) paste(x@a, '|', x@b))
cell_matrix <- function(...) {
structure(matrix(...), class="cell_matrix")
}
print.cell_matrix <- function(x, ...) {
mat.char <- lapply(x, as.character)
dim(mat.char) <- dim(x)
print(mat.char)
}
mat1 <- cell_matrix(c(cell1, cell1, cell1, cell1), nrow=2)
mat1
Produces:
[,1] [,2]
[1,] "hello | world" "hello | world"
[2,] "hello | world" "hello | world"
Here I got lazy and mixed S3 and S4 classes, but if you're doing this in a package, you may want to implement an S4 cellMatrix
class, and define an as.character
method for that class, rather than just for a single cell.
Note that this is likely to be relatively inefficient as you are creating objects for each cell, and you are then iterating through each cell. I would create vectors that contain all the a
values for all cells, and all the b
values for all cells, and then create logic that makes it look like the elements are individual. Things will be much faster that way.
Upvotes: 2