2013-10-26 2 views
8

Часто упоминается, что data.frame наследует от list, что имеет смысл, учитывая многие распространенные парадигмы для доступа к столбцам data.frame ($, sapply и т. Д.).Почему класс (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 

Два вопроса затем:

  1. ли отказ иметь data.frame формально наследуемые от list имеют каких-либо преимуществ от точки зрения дизайна?
  2. Как эти функции, которые, как представляется, относятся к data.frame, так как списки знают, что они рассматривают их как списки? От взгляда на lapply похоже, что он быстро переходит к внутреннему коду C, так что, возможно, так оно и есть, но мой ум немного взорван здесь.
+4

Я предполагаю, что это сводится к эффективности. Отправка метода S3 является дорогостоящей, а списки являются очень базовой структурой данных в R. Таким образом, они рассматриваются на уровне C. Например, даже 'is.list' является примитивным (в отличие от' is.data.frame'). – Roland

+4

Тот, кто говорит 'data.frame' _inherits_ из' list', ошибочен. Вероятно, они означают, что data.frames реализуются как список с определенными атрибутами и характеристиками. 'lapply' вызывает' as.list', если 'X' не является вектором, или если' is.object' является 'TRUE' (в основном, если есть атрибут' class'). 'as.list' является общим с методом' data.frame'. –

+4

Я немного обсуждаю это в http://adv-r.had.co.nz/OO-essentials.html#method-dispatch. @JoshuaUlrich Я не думаю, что необоснованно говорить, что data.frame наследуется от списка, но это сложно, потому что список и фрейм данных не принадлежат к одной и той же объектной системе. – hadley

ответ

1

Я признаю, что классы в R немного запутывают меня. Но я помню, как однажды прочитал что-то вроде «In R data.frames - это фактически списки векторов». Использование кода из вашего примера, мы можем убедиться в этом:

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

Обратите внимание, что мы также можем использовать оператор [[]] для доступа к элементам (столбцы) dat, который является обычным способом для доступа к элементам списков в R :

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

Мы также можем убедиться, что каждый столбец фактически является вектор:

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

 Смежные вопросы

  • Нет связанных вопросов^_^