I have an issue verifying the validity of my class 'class2'; it is made of a list of 'class1' objects. I want to verify that it is indeed the case:
class2 <- setClass(
Class = "class2",
slots = c(slotListName = "list"),
validity = function(object){
lapply(object@slotListName, function(x){
if(!identical(is(x), "class1"))
stop(" not a class1 object");
});
});
The problem is that lapply returns values which are not accepted:
Error in validObject(.Object) :
invalid class “class2” object: 1: NULL
invalid class “class2” object: 2: NULL
I checked that the problem was coming from the lapply by testing only the first element of the list, which is working fine:
if(!identical(is(object@slotListName[[1]]), "class1"))
stop("not a class1 object");
I tried vectorizing but this does not change the problem.
Is there a way to verify that slotListName is indeed a list of 'class1' objects?
Thanks a lot!
The problem with your function is that it gives an error for an invalid object. It's supposed to return a diagnostic message, with the S4 object construction machinery taking care of the error.
Here's how you can do it using the recommended approach, which is to define methods for initialize
and setValidity
. See ?setClass
for more details.
class2 <- setClass("class2", slots=c(slotListName="list"))
setMethod("initialize", "class2", function(.Object, lst)
{
.Object@slotListName <- lst
validObject(.Object)
.Object
})
# returns TRUE if the object is valid, otherwise a diagnostic message
setValidity("class2", function(object)
{
if(length(object@slotListName) < 1)
"must contain at least one class1 object"
else if(!all(sapply(object@slotListName, function(x) inherits(x, "class1"))))
"all objects in list must be class1"
else TRUE
})
## testing
x <- 42
class(x) <- "class1"
y <- 43
class(y) <- "bad"
l1 <- list(x, x, x)
l2 <- list(x, x, y)
## works
obj1 <- class2(l1)
## error: bad object in list
obj2 <- class2(l2)
## error: empty list
obj3 <- class2(list())