30

I need a bit of help with jargon, and a short piece of example code. Different types of objects have a specific way of outputting themselves when you type the name of the object and hit enter, an lm object shows a summary of the model, a vector lists the contents of the vector.

I'd like to be able to write my own way for "showing" the contents of a specific type of object. Ideally, I'd like to be able to seperate this from existing types of objects.

How would I go about doing this?

Brandon Bertelsen
  • 43,807
  • 34
  • 160
  • 255
  • 1
    Perhaps see `?Methods` - there are examples near the bottom of the page. – BenBarnes Jun 07 '12 at 19:24
  • 1
    Be careful if you are trying to alter the print method of an S3 class object provided by a package with a NAMESPACE, which is all packages with a modern version of R. If you write a new `print()` method for an existing class, you may need to `assignInNamespace(....)` your local version of the print method. – Gavin Simpson Jun 07 '12 at 19:39
  • Thanks for the direction Ben and the tip Gavin. – Brandon Bertelsen Jun 07 '12 at 19:41

1 Answers1

33

Here's an example to get you started. Once you get the basic idea of how S3 methods are dispatched, have a look at any of the print methods returned by methods("print") to see how you can achieve more interesting print styles.

## Define a print method that will be automatically dispatched when print()
## is called on an object of class "myMatrix"
print.myMatrix <- function(x) {
    n <- nrow(x)
    for(i in seq_len(n)) {
        cat(paste("This is row", i, "\t: " ))
        cat(x[i,], "\n")
        }
}

## Make a couple of example matrices
m <- mm <- matrix(1:16, ncol=4)

## Create an object of class "myMatrix". 
class(m) <- c("myMatrix", class(m))
## When typed at the command-line, the 'print' part of the read-eval-print loop
## will look at the object's class, and say "hey, I've got a method for you!"
m
# This is row 1   : 1 5 9 13 
# This is row 2   : 2 6 10 14 
# This is row 3   : 3 7 11 15 
# This is row 4   : 4 8 12 16 

## Alternatively, you can specify the print method yourself.
print.myMatrix(mm)
# This is row 1   : 1 5 9 13 
# This is row 2   : 2 6 10 14 
# This is row 3   : 3 7 11 15 
# This is row 4   : 4 8 12 16 
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • Exactly what I needed. My language was all wrong "type" = "class", "way of outputting" = "method" – Brandon Bertelsen Jun 07 '12 at 19:30
  • The point of mm was to show me that the object didn't have to be of class "myMatrix" for the print function to work? – Brandon Bertelsen Jun 07 '12 at 19:42
  • Yeah. I basically included it to help demystify the whole subject, and to show that the `print.myMatrix` is just another function that could be applied to any object. The only thing special about it is the `.myMatrix` part of it's name, which allows it to be found by the `UseMethod` call that invoked when a call to `print()` is evaluated. Not sure how successful it was, but that was my intent. – Josh O'Brien Jun 07 '12 at 19:49
  • 2
    I changed `j[i,]` to `x[i,]` since it was throwing errors. I was tempted to change: `class(m) <- "myMatrix"` to `class(m) <- c("myMatrix", class(m))` so that your new class could inherit from "matrix" methods, but decided I would only suggest that you do so. – IRTFM Jun 07 '12 at 20:37