I have a number of S4 objects with a variable number of slots and slotnames. The data in each slot is the same length. For example the S4 object peaks
:
> str(peaks)
Formal class 'MassPeaks' [package "MALDIquant"] with 4 slots
..@ snr : num [1:16] 37.81 9.18 8.65 4.66 53.22 ...
..@ mass : num [1:16] 307 317 325 337 347 ...
..@ intensity: num [1:16] 2255 547 516 278 3173 ...
..@ metaData : list()
I want to turn these S4 objects into dataframes. For example the dataframe df.peaks
:
> str(df.peaks)
'data.frame': 16 obs. of 3 variables:
$ snr : num 37.81 9.18 8.65 4.66 53.22 ...
$ mass : num 307 317 325 337 347 ...
$ intensity: num 2255 547 516 278 3173 ...
Is there a general way to do this? For this example I can do
> df.peaks = data.frame(snr=peaks@snr, mass=peaks@mass, intensity=peaks@intensity)
but that requires hardcoding the slotnames of the S4 object. How do I do it without hardcoding the slotnames? I could do it by getting s4.names = slotNames(peaks)
, but in this case I don't know how to use s4.names
to access the slots of peaks
.
The S4 system in R is a system for object oriented programing. Confusingly, R has support for at least 3 different systems for object oriented programming: S3, S4 and S5 (also known as reference classes).
Example 2: Creation of S4 object We can check if an object is an S4 object through the function isS4() . The function setClass() returns a generator function. This generator function (usually having same name as the class) can be used to create new objects. It acts as a constructor.
A slot name can be any non-empty string, but if the name is not made up of letters, numbers, and . , it needs to be quoted (by backticks or single or double quotes). In the case of the slot function, name can be any expression that evaluates to a valid slot in the class definition.
I don't know about the "right" way to do this, as I very rarely use S4 objects. Here's a stab at it though:
# from the ?slot page
setClass("track", slots = c(x="numeric", y="numeric"))
myTrack <- new("track", x = -4:4, y = exp(-4:4))
str(myTrack)
Formal class 'track' [package ".GlobalEnv"] with 2 slots ..@ x: int [1:9] -4 -3 -2 -1 0 1 2 3 4 ..@ y: num [1:9] 0.0183 0.0498 0.1353 0.3679 1 ...
The approach here is to get the slot names, and then iterate over them one at a time, extracting into a list of the contents of each slot. Then give the list-elements the appropriate names (from the slots), and bind it into a dataframe.
# conversion function
S4_to_dataframe <- function(s4obj) {
nms <- slotNames(s4obj)
lst <- lapply(nms, function(nm) slot(s4obj, nm))
as.data.frame(setNames(lst, nms))
}
S4_to_dataframe(myTrack)
x y 1 -4 0.01831564 2 -3 0.04978707 3 -2 0.13533528 4 -1 0.36787944 5 0 1.00000000 6 1 2.71828183 7 2 7.38905610 8 3 20.08553692 9 4 54.59815003
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