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

Ari*_*man 8 r r-s3

人们常常说,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"
Run Code Online (Sandbox Code Playgroud)

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

> class(unclass(dat))
[1] "list"
Run Code Online (Sandbox Code Playgroud)

如果没有data.frame方法,测试它看起来像默认方法将优先调用list方法:

> 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
Run Code Online (Sandbox Code Playgroud)

那么两个问题:

  1. 从设计的角度来看,未能data.frame正式继承是否list有任何优势?
  2. 那些似乎将data.frames视为列表的函数如何知道将它们视为列表?看起来lapply它看起来很快就会转到C内部代码,所以也许就是这样,但我的思绪在这里有点夸张.

Ari*_*Ari 1

我承认 R 中的类也让我有点困惑。但我记得曾经读过类似“在 R data.frames 实际上是向量列表”之类的内容。使用您示例中的代码,我们可以验证这一点:

> is.list(dat)
[1] TRUE
?is.list
Run Code Online (Sandbox Code Playgroud)

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

> identical(dat$x, dat[[1]])
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

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

> is.vector(dat$x)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)