Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't class(data.frame(...)) show list inheritance?

Tags:

r

r-s3

It's often said that data.frame inherits from list, which makes sense given many common paradigms for accessing data.frame columns ($, sapply, etc.).

Yet "list" is not among the items returned in the class list of a data.frame object:

dat <- data.frame(x=runif(100),y=runif(100),z=runif(100),g=as.factor(rep(letters[1:10],10)))
> class(dat)
[1] "data.frame"

Unclassing a data.frame shows that it's a list:

> class(unclass(dat))
[1] "list"

And testing it does look like the default method will get called in preference to the list method if there's no data.frame method:

> f <- function(x) UseMethod('f')
> f.default <- function(x) cat("Default")
> f.list <- function(x) cat('List')
> f(dat)
Default
> f.data.frame <- function(x) cat('DF')
> f(dat)
DF

Two questions then:

  1. Does the failure to have data.frame formally inherit from list have any advantages from a design perspective?
  2. How do those functions that seem to treat data.frames as lists know to treat them as lists? From looking at lapply it looks like it goes to C internal code quite quickly, so perhaps that's it, but my mind's a little blown here.
like image 526
Ari B. Friedman Avatar asked Oct 26 '13 14:10

Ari B. Friedman


People also ask

Can we make list of DataFrame?

To create a list of Dataframes we use the list() function in R and then pass each of the data frame you have created as arguments to the function.

How do I know if a DataFrame is data in R?

frame() function in R Language is used to return TRUE if the specified data type is a data frame else return FALSE.


1 Answers

I confess that classes in R are a bit confusing to me as well. But I remember once reading something like "In R data.frames are actually lists of vectors". Using the code from your example, we can verify this:

> is.list(dat)
[1] TRUE
?is.list

Note that we can also use the [[]] operator to access the elements (columns) of dat, which is the normal way to access elements of lists in R:

> identical(dat$x, dat[[1]])
[1] TRUE

We can also verify that each column is actually a vector:

> is.vector(dat$x)
[1] TRUE
like image 159
Ari Avatar answered Sep 24 '22 16:09

Ari