r语言 - 为什么 class(data.frame(...)) 不显示列表继承?



人们常说data.frame继承自list,考虑到许多访问data.frame列的常见范式($sapply等),这是有道理的。

然而,"list"不在data.frame对象的类列表中返回的项之列:

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"

取消分类data.frame会显示它是一个列表:

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

并且测试它看起来确实像在没有 data.frame 方法的情况下优先调用默认方法而不是列表方法:

> 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

那么两个问题:

  1. 设计的角度来看,无法正式继承data.frame list有什么好处吗?
  2. 那些似乎将data.frame视为列表的函数如何知道将它们视为列表? 从lapply看,它看起来很快就进入了 C 内部代码,所以也许就是这样,但我的想法在这里有点爆炸。

我承认R中的类对我来说也有点困惑。 但我记得曾经读过类似"在 R data.frame 实际上是向量列表"之类的东西。 使用示例中的代码,我们可以验证这一点:

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

注意我们也可以使用 [[]] 运算符来访问 dat 的元素(列),这是访问 R 中列表元素的常规方式:

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

我们还可以验证每列实际上是一个向量:

> is.vector(dat$x)
[1] TRUE

最新更新