我有一个整数文本文件,我一直在读R并暂时存储为数据框。但是,将它强制转换为矩阵(例如y
,使用as.matrix()
)似乎与我创建的矩阵(x
)不同。也就是说,如果我查看单个条目,我会得到不同的输出
> y[1,1]
V1
0
而不是
> x[1,1]
[1] 0
任何人都可以解释这种差异吗?
答案 0 :(得分:6)
我将您的问题解释为询问矩阵和数据框之间的区别,而不仅仅是y[1,1]
的输出在y
是数据框与矩阵的情况下的原因。如果您只想知道它们看起来不同的原因那么答案就是数据框架和矩阵是不同的类并且具有不同的内部表示,尽管已经设计并实现了许多操作来描述最终矩阵索引和数据框架的差异。索引是单独实现的,并不一定必须相同,尽管希望它们合理地一致地实现。在这一点上,修改R以减少任何不一致性可能是不明智的,因为它可能会破坏多少代码。
矩阵矩阵是具有维度的向量。
m1 <- 1:12
dim(m1) <- c(4, 3)
m2 <- matrix(1:12, 4, 3)
identical(m1, m2)
## [1] TRUE
length(m1) # 12 elements in the underlying vector
## [1] 12
数据框
data.frame是具有行名称的列的命名列表(名称是列名称) - 默认行名称1,2,...在内部表示为c(NA, -4L)
用于4行数据框,以避免必须存储可能大的行名称向量。
DF1 <- as.data.frame(m1)
DF2 <- list(V1 = 1:4, V2 = 5:8, V3 = 9:12)
attr(DF2, "row.names") <- c(NA, -4L)
class(DF2) <- "data.frame"
identical(DF1, DF2)
## [1] TRUE
length(DF1) # 3 columns
## [1] 3
名称
矩阵不必具有行名或列名,而数据框总是如此。如果矩阵具有行名和列名,则它们表示为两个称为dimnames的向量的列表(与具有row.names属性的命名列表相对,该属性是数据框表示其行名的方式)。
m3 <- m1
rownames(m3) <- c("a", "b", "c", "d")
colnames(m3) <- c("A", "B", "C")
str(m3)
## int [1:4, 1:3] 1 2 3 4 5 6 7 8 9 10 ...
## - attr(*, "dimnames")=List of 2
## ..$ : chr [1:4] "a" "b" "c" "d"
## ..$ : chr [1:3] "A" "B" "C"
m4 <- m1
dimnames(m4) <- list(c("a", "b", "c", "d"), c("A", "B", "C"))
identical(m3, m4)
## [1] TRUE
<强> lapply 强>
假设我们对矩阵m1进行了讨论。因为它实际上是一个具有维度的向量,所以我们对12个元素中的每一个进行了应用:
> str(lapply(m1, length))
List of 12
$ : int 1
$ : int 1
$ : int 1
$ : int 1
$ : int 1
$ : int 1
$ : int 1
$ : int 1
$ : int 1
$ : int 1
$ : int 1
$ : int 1
如果我们在DF1
之上执行此操作,那么我们将使用超过3个元素,每个元素的长度为4
> str(lapply(DF1, length))
List of 3
$ V1: int 4
$ V2: int 4
$ V3: int 4
双重索引 索引是这样的,如果矩阵没有名称,DF1 [1,1]和m1 [1,1]给出相同的结果。
DF1[1,1]
## [1] 1
m1[1,1]
## [1] 1
如果确实如此,则存在观察到的差异:
as.matrix(DF1)[1,1] # as.matrix(DF1) has col names V1, V2, V3 from DF1
V1
1
DF1[1,1]
[1] 1
将矩阵转换为数据帧时必须小心,因为如果数据框中有字符和数字列,则转换将强制它们全部为相同类型,即全部为字符。
单个索引
然而,如果我们像这样索引,那么由于数据帧是列的列表,我们得到由第一列构成的数据框
> DF1[1]
V1
1 1
2 2
3 3
4 4
但是对于矩阵,因为它是具有维度的向量,我们得到该向量的第一个元素
> m1[1]
[1] 1
其他强>
在通常情况下,矩阵的所有元素都是数字,或者都是字符,但对于数据框,每列可能不同。一列可能是数字,而另一列可能是字符或逻辑。
通常,对矩阵的操作比对数据帧的操作要快。
答案 1 :(得分:0)
分配给数据结构的属性还取决于用于导入或读取数据的方法,以及是使用其他函数显式定义还是强制它们。
这是一个名为integers
的数据框,通过从.txt
文件导入数据而创建。
> integers
V1 V2 V3
1 1 5 9
2 2 6 10
3 3 7 11
4 4 8 12
以下是将m.integers
传递给integers
as.matrix()
的矩阵的数据
as.matrix(integers)
> m.integers
V1 V2 V3
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
这是一个名为m2
的矩阵,如上所述使用matrix()
> m2
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
现在选择每个结构的第一个元素给出以下内容。 另外,查看每个属性的属性会显示每个属性的默认值(如果指定了任何值,则为赋值)。
# The element is given a row name.
> integers[1,1]
[1] 1
# Notice attributes$row.names
> attributes(integers)
$names
[1] "V1" "V2" "V3"
$class
[1] "data.frame"
$row.names
[1] 1 2 3 4
#################################################
# The element is given a column name.
> m.integers[1,1]
V1
1
# Notice there is no row name attribute
> attributes(m.integers)
$dim
[1] 4 3
$dimnames
$dimnames[[1]]
NULL
$dimnames[[2]]
[1] "V1" "V2" "V3"
###############################################
# The element is given a row name.
> m2[1,1]
[1] 1
# Notice no row name attribute.
> attributes(m2)
$dim
[1] 4 3
根据data.frame()
的文档,row.names = NULL
的默认值和行名称设置为从[1]
开始的整数序列。并且as.matrix()
不会保留行名称。将数据框传递给as.matrix()
时,将保留列名称。如果在使用matrix()
时未分配,则Rownames也会自动指定为整数序列。
如有必要,可以更改行名称。
> attributes(integers)$row.names <- c("one", "two", "three", "four")
> integers
V1 V2 V3
one 1 5 9
two 2 6 10
three 3 7 11
four 4 8 12
> attributes(integers)$row.names <- c("one", "two", "three", "four")
> integers
V1 V2 V3
one 1 5 9
two 2 6 10
three 3 7 11
four 4 8 12
> attributes(m.integers)$dimnames[[2]] <- NULL
> m.integers
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> attributes(m.integers)$dimnames[[1]] <- c("one", "two", "three", "four")
> m.integers
[,1] [,2] [,3]
one 1 5 9
two 2 6 10
three 3 7 11
four 4 8 12