Reputation: 4907
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 print
and summary
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.
setClass("foo",
representation= list(method= "character",
mle_iter= "numeric",
mle_log_lik= "numeric",
data= "list"))
print.foo <- function(obj) {
cat("\n Method: ", obj@method,
"\n\n Iterations: ", obj@mle_iter,
"\n\n Log-Likelihood: ", obj@mle_log_lik)
}
setGeneric("print",
def= function(obj) {
print.foo(obj)
standardGeneric("print")
})
setMethod("print", signature= "foo",
function(obj) {
print(obj)
})
dat <- as.data.frame(matrix(rnorm(500), ncol=5))
foo1 <- new("foo",
method= "EM",
mle_iter= 6,
mle_log_lik= 1000,
data= list(dat))
class(foo1)
# this gives me the print that I want; but throws two errors
# other things that I've tried have just done evaluated print.default()
print(foo1)
## Summary
setGeneric("summary")
summary.foo <- function(obj) {
print(obj)
lapply(obj@data, dim)
}
setMethod("summary", signature= "foo",
summary.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!
Upvotes: 1
Views: 622
Reputation: 46866
S4 uses show()
rather than print. The generic already exists
getGeneric("show")
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
summary.foo <- function(object, ...) {
## implement summary.foo
"I'm a foo"
}
setMethod("summary", "foo", 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")
summary.foo <- function(object, ...) {
## implement summary.foo
"I'm a foo"
}
setMethod("summary", "foo", 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.
Upvotes: 1