我目前正在阅读Hands-on Programming with R。作者写了以下段落 -
类是原子向量的特例。例如,模具 矩阵是双向量的特例。中的每一个元素 矩阵仍然是一个双重,但元素已被排列成一个 新结构。当你改变它时,R添加了一个class属性 尺寸。这个类描述了die的新格式。许多R功能 将专门查找对象的类属性,然后 基于属性以预定方式处理对象。
根据我的理解,不应该反过来说这个陈述 - 向量是矩阵的一个特例,因为它的维度是Nx1
而不是NxM
。相似性,不应该是一个类的特殊情况,因为向量具有NULL
类。
为什么不是这样?
答案 0 :(得分:3)
作者所指的(以一种糟糕的方式),是对象的内部表示。它们都是某种类型的“列表”,其中包含额外的信息,用于定义R如何处理它。
以矩阵为例。矩阵是具有称为“暗淡”的额外属性的向量。正是这个属性使它成为一个矩阵。删除属性,显示基础矢量结构:
> x <- matrix(1:10, ncol = 5)
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
> attributes(x)
$dim
[1] 2 5
> attr(x,"dim") <- NULL
> x
[1] 1 2 3 4 5 6 7 8 9 10
另一方面,数据框是列表的特例。它们又被属性定义为S3类。这次该属性称为“类”。
S3系统是OOP的一个非常基本的实现:没有正式的类定义,因此实例的类只由属性定义。像print()
,summary()
这样的通用函数会查看该类属性,并搜索该类的特定方法。
请注意属性是一个命名列表,其中包含有关该对象的额外信息。对于数据框,这是类属性本身旁边的行名和列名:
> class(iris)
[1] "data.frame"
> attributes(iris)
$names
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
$row.names
[1] 1 2 3 4 5 ...
$class
[1] "data.frame"
> class(iris) <- NULL
> class(iris)
[1] "list"
S3类的其他实例也由该属性“class”定义。例如,如果您执行线性模型,则输出是具有类属性的列表,该类属性使其为类“lm”。删除class属性会为您留下命名列表。
在谈到S4时,事情变得有点复杂。但同样S4对象是类似列表的结构,其中每个槽都是该“列表”的“元素”。请注意,您无法删除属性,因此无法像使用S3类一样访问常规列表。 S4被更严格地定义,因此作者所表达的一般想法不适用于S4对象。
回答关于向量和矩阵的问题:向量在R中没有维度。或者更确切地说:它没有维度属性。您可以添加一个,但最终会得到一维数组。它们的行为与矢量非常相似,但并非总是如此。因此矩阵在内部是一个带有一小部分额外信息的向量。我不会称之为“矢量的特殊情况”,但确实矩阵是从矢量中导出的,而不是相反的。