I am having some trouble converting my S4 object back into a list. Take for example, the following nested S4 classes:
setClass("nssItem",
representation(value = "numeric", text = "character", prefix = "character", type = "character"),
prototype(value = as.numeric(NA), text = as.character(NA), prefix = as.character(NA), type = as.character(NA))
)
setClass("geckoNss", representation(absolute = "character", item = "nssItem"))
An object of geckoNss class contains objects of nssItem class. Conceptually this seems like a list-like structure which allows for nesting.
Yet,
> temp <- new("nssItem")
> as.list(temp)
Error in as.list.default(temp) :
no method for coercing this S4 class to a vector
I understand this error, that is, I have not actually defined what as.list means or how it applies with respect to the nssItem class. Nonetheless, this seems like a very natural operation. How would I extend the definition of as.list to all new classes I define?
This is a second, more general solution. It uses a superclass from which you derive all user-defined classes. Descriptions are in the # comments.
#this is an "empty" superclass that characterises all user-defined classes
setClass("user_defined_class")
#we create an as.list method for this new superclass (this time an S4 method)
setMethod("as.list",signature(x="user_defined_class"),function(x) {
mapply(function(y) {
#apply as.list if the slot is again an user-defined object
#therefore, as.list gets applied recursively
if (inherits(slot(x,y),"user_defined_class")) {
as.list(slot(x,y))
} else {
#otherwise just return the slot
slot(x,y)
}
},
slotNames(class(x)),
SIMPLIFY=FALSE)
})
setClass("nssItem",
representation(value = "numeric",
text = "character",
prefix = "character",
type = "character"),
prototype(value = as.numeric(NA),
text = as.character(NA),
prefix = as.character(NA),
type = as.character(NA)),
#note the contains argument that flags the nssItem class as user-defined
contains="user_defined_class")
setClass("geckoNss",
representation(absolute = "character", item = "nssItem"),
#the same for the geckoNss class
contains="user_defined_class")
Now create one object for each class
temp <- new("nssItem")
tempGecko<-new("geckoNss")
Coerce temp to list
as.list(temp)
#$value
#[1] NA
#
#$text
#[1] NA
#
#$prefix
#[1] NA
#
#$type
#[1] NA
And the tempGecko object
as.list(tempGecko)
#$absolute
#character(0)
#
#$item
#$item$value
#[1] NA
#
#$item$text
#[1] NA
#
#$item$prefix
#[1] NA
#
#$item$type
#[1] NA
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With