Dear r-devel list members, I'm moving this question to r-devel because it seems thornier than I originally thought.
I've already mentioned (on r-help) that the approach that John Chambers suggested (below) fails for objects of class "by": > x <- rnorm(100) > y <- sample(2, 100, replace=TRUE) > res <- by(x, y, mean) > res INDICES: 1 [1] -0.03429679 ------------------------------------------------------------ INDICES: 2 [1] -0.1273790 > class(res) [1] "by" > isS4object <- function(object)(length(attr(object, "class"))==1 && + !is.null(getClass(class(object)))) > isS4object(res) Error in getClass(class(object)) : "by" is not a defined class > I tried to fix that, but I've now discovered more general problems; e.g.: > mod <- lm(y ~ x) > class(mod) [1] "lm" > isS4object(mod) [1] TRUE > class(summary(mod)) [1] "summary.lm" > isS4object(summary(mod)) Error in getClass(class(object)) : "summary.lm" is not a defined class > I've reverted to a modified version of my original proposal: > isS4object <- function(object) { + !(length(object) == 1 && class(object) == "character") && length(slotNames(object)) != 0 + } > isS4object(res) [1] FALSE > isS4object(mod) [1] FALSE > isS4object(summary(mod)) [1] FALSE > # example from ?mle > x <- 0:10 > y <- c(26, 17, 13, 12, 20, 5, 9, 8, 5, 4, 8) > ll <- function(ymax=15, xhalf=6) + -sum(stats::dpois(y, lambda=ymax/(1+x/xhalf), log=TRUE)) > fit <- mle(ll) Warning message: NaNs produced in: dpois(x, lambda, log) > isS4object(fit) [1] TRUE > isS4object("mle") [1] FALSE > All this is with R 2.0.1 under Windows NT. Comments would be appreciated. John -------------------------------- John Fox Department of Sociology McMaster University Hamilton, Ontario Canada L8S 4M4 905-525-9140x23604 http://socserv.mcmaster.ca/jfox -------------------------------- > -----Original Message----- > From: John Chambers [mailto:[EMAIL PROTECTED] > Sent: Tuesday, November 30, 2004 9:40 AM > To: John Fox > Cc: Martin Maechler; [EMAIL PROTECTED] > Subject: Re: [R] Testing for S4 objects > > Let me suggest a different test, because slotNames was > written to work differently when given a string or a class > definition. With your definition, > > R> x <- "classRepresentation" > R> isS4object(x) > [1] TRUE > > which I assume is not what you wanted. (Given a single string, > slotNames() tries to look up the class definition of that name.) > > How about the following? The logic is that an S4 object must > have an actual class attribute of length 1 (that rules out > basic data types, where class(x) is a string but there is no > actual attribute, and also rules out some S3 objects). Then > if that's true, try to look up the class definition. If it > is non-null, seems like an S4 object. > > R> isS4object <- function(object)(length(attr(object, "class"))==1 && > + !is.null(getClass(class(object)))) > R> isS4object(x) > [1] FALSE > R> isS4object(getClass(class(x))) > [1] TRUE > > This definition seems to work, at least on the examples I > could think of right away. Notice though, that some classes, > such as "ts", that have been around for a long while are > nevertheless legitimate S4 classes, so: > > R> t1 = ts(1:12) > R> isS4object(t1) > [1] TRUE > > (this applies to either version of isS4object). > > There are a couple of details, more appropriate for the r-devel list. > Seems a good candidate for a function to add to R. > > > On Sat, 27 Nov 2004 17:48:30 -0500, John Fox <[EMAIL PROTECTED]> wrote: > > Dear Martin, > > > > As it turns out, the test that I proposed (i.e., testing for NULL > > slotNames) sometimes fails. For example: > > > > > library(car) > > > data(Prestige) > > > sum <- summary(lm(prestige ~ income + education, data=Prestige)) > > > slotNames(sum) > > character(0) > > > > The following, however, seems to work (at least as far as I've been > > able to > > ascertain): > > > > isS4object <- function(object) length(slotNames(object)) != 0 > > > > I hope that this is a more robust test. > > > > > > > > John > > > > -------------------------------- > > John Fox > > Department of Sociology > > McMaster University > > Hamilton, Ontario > > Canada L8S 4M4 > > 905-525-9140x23604 > > http://socserv.mcmaster.ca/jfox > > -------------------------------- > > > > > -----Original Message----- > > > From: Martin Maechler [mailto:[EMAIL PROTECTED] > > > Sent: Friday, November 26, 2004 3:18 AM > > > To: John Fox > > > Cc: [EMAIL PROTECTED] > > > Subject: Re: [R] Testing for S4 objects > > > > > > >>>>> "JohnF" == John Fox <[EMAIL PROTECTED]> > > > >>>>> on Thu, 25 Nov 2004 22:28:50 -0500 writes: > > > > > > JohnF> Dear r-help list members, Is there a way to test > > > JohnF> whether an object is an S4 object? The best that I've > > > JohnF> been able to come up with is > > > > > > JohnF> isS4object <- function(object) > > > !(is.null(slotNames(object))) > > > > > > you can drop one pair of "(..)" to give > > > > > > isS4object <- function(object) !is.null(slotNames(object)) > > > > > > > > > JohnF> which assumes that an S4 object has at least one > > > JohnF> slot. I think this is safe, but perhaps I'm missing > > > JohnF> something. > > > > > > The question is a very good one -- that I have posed to R-core a > > > while ago myself. > > > > > > Inside utils:::str.default {which doesn't show the many > commments > > > in the *source* of str.default()}, I have wanted a way that even > > > works when the 'methods' package is not attached and use the more > > > obscure > > > > > > #NOT yet:if(has.class <- !is.null(cl <- class(object))) > > > if(has.class <- !is.null(cl <- attr(object, "class")))# > > > S3 or S4 class > > > S4 <- !is.null(attr(cl, "package"))## <<<'kludge' FIXME! > > > ##or length(methods::getSlots(cl)) > 0 > > > > > > For the time being, I'd keep your function, but I don't > think we'd > > > guarantee that it will remain the appropriate test in all > future. > > > But till then many things will have happened (if not all of them > > > ;-). > > > > > > Martin Maechler, ETH Zurich > > > > > > > ______________________________________________ > > [EMAIL PROTECTED] mailing list > > https://stat.ethz.ch/mailman/listinfo/r-help > > PLEASE do read the posting guide! > > http://www.R-project.org/posting-guide.html > > ______________________________________________ [EMAIL PROTECTED] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel