Alex W Alex W - 1 year ago 61
R Question

properly specify S4 generics

Sorry for my ignorance, but I do not understand how to properly implement S4 generics. I've been struggling for the past few hours. Hopefully it's a simple fix.

I'm trying to define simple methods such as

for my class. I've tried a bunch of different variations to the below. What is below seems to be the closest thing to working but still clearly not proper.

What is the proper way to do this? What am I doing wrong?

representation= list(method= "character",
mle_iter= "numeric",
mle_log_lik= "numeric",
data= "list")) <- function(obj) {
cat("\n Method: ", obj@method,
"\n\n Iterations: ", obj@mle_iter,
"\n\n Log-Likelihood: ", obj@mle_log_lik)

def= function(obj) {

setMethod("print", signature= "foo",
function(obj) {

dat <-, ncol=5))

foo1 <- new("foo",
method= "EM",
mle_iter= 6,
mle_log_lik= 1000,
data= list(dat))


# this gives me the print that I want; but throws two errors
# other things that I've tried have just done evaluated print.default()

Summary method

## Summary
setGeneric("summary") <- function(obj) {

lapply(obj@data, dim)

setMethod("summary", signature= "foo",

summary(foo1) # works for this toy example. Doesn't work with my real code
# output for my real example
> Length Class Mode
1 mod_imputeMulti S4

I assume this is a simple fix to my ignorance, but I'm not sure what. Thanks in advance!

Answer Source

S4 uses show() rather than print. The generic already exists


so your job is to implement a method

setMethod("show", "foo", function(object) {
    cat("I'm a foo\n")

summary is an S3 generic and from ?Methods the advice is to implement an S3 method and an S4 method <- function(object, ...) {
    ## implement
    "I'm a foo"

setMethod("summary", "foo",

The last line has as a side-effect the creation of an S4 generic on "summary" for reasons outlined on ?Methods; it may be useful to create the S4 generic explicitly,

setGeneric("summary") <- function(object, ...) {
    ## implement
    "I'm a foo"

setMethod("summary", "foo",

before setting the method on it.

If you were to implement an entirely new generic and method, then code would follow the pattern

setGeneric("bar", function(x, ...) standardGeneric("bar"))

setMethod("bar", "foo", function(x, ...) {
    ## implement 'bar,foo-method'

In this case there would be no need to create an S3 generic or S3 method.