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:
- Does the failure to have
data.frame
formally inherit fromlist
have any advantages from a design perspective? - How do those functions that seem to treat
data.frame
s as lists know to treat them as lists? From looking atlapply
it looks like it goes to C internal code quite quickly, so perhaps that's it, but my mind's a little blown here.