8
人們常說,data.frame
繼承自list
,這對於訪問data.frame列($
,sapply
等)有許多常見的範例是有意義的。爲什麼class(data.frame(...))不顯示列表繼承?
然而"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"
Unclassing一個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
個
兩個問題,那麼:
- 是否未能有
data.frame
正式繼承list
具有從設計的角度來看有什麼優勢? - 那些似乎將
data.frame
s作爲列表的函數如何知道將它們視爲列表?從lapply
看起來它很快就會轉到C語言的內部代碼,所以也許就是這樣,但是我的想法在這裏有一點點。
我猜它歸結爲工作效率。 S3方法調度是昂貴的,並且列表是R中非常基本的數據結構。因此,它們在C級處理。例如,即使'is.list'也是一個原語(與「is.data.frame」相反)。 – Roland
誰從'list'中說'data.frame' _inherits_是錯誤的。它們可能意味着data.frames被實現爲具有特定屬性和特徵的列表。如果'X'不是一個向量,或者'is.object'是'TRUE'(基本上是有'class'屬性的話),'lapply'會調用'as.list'。 'as.list'與'data.frame'方法是通用的。 –
我在http://adv-r.had.co.nz/OO-essentials.html#method-dispatch中對此進行了一些討論。 @JoshuaUlrich我認爲說data.frame從列表繼承是不合理的,但它很複雜,因爲列表和數據框不屬於同一個對象系統。 – hadley