Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

General way to transform S4 object to dataframe (R)

Tags:

dataframe

r

s4

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.

like image 507
R Greg Stacey Avatar asked Aug 01 '19 22:08

R Greg Stacey


People also ask

What is an S4 object in R?

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).

How do you create S4 objects How can you check an object is S4 object?

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.

What is a slot in R?

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.


Video Answer


1 Answers

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
like image 52
Brian Avatar answered Sep 22 '22 09:09

Brian