似乎 data.frames
继承了矩阵的列名,如果矩阵是通过 [
函数添加到它们的。示例:
blob <- matrix(11:20, ncol = 1, dimnames = list(NULL, "BLOB"))
foo <- data.frame(FOO = 201:210)
dat <- data.frame(id = 1:10)
dat[, "new1"] <- blob
dat[, "new2"] <- foo
如果我现在查看dat
,它会显示我
id BLOB new2
1 11 201
2 12 202
3 13 203
...
因此显示的不是预期的"new1"
,而是"BLOB"
;即使 colnames(dat)
是 "id"
、"new1"
和 "new2"
。此外,在 attributes(dat)
中找不到 "BLOB"
并且 dat[, "BLOB"]
给出了“未定义的列选择”错误.
两个问题:
- 为什么
dat
在这种情况下显示"BLOB"
而不是"new1"
? - 如何以显示
"new1"
而不是"BLOB"
的方式更改dat
?
最佳答案
将整个矩阵分配给 data.frame 的列会创建一个非常奇怪的对象。如果您查看 dat
的结构,您会看到
'data.frame': 10 obs. of 3 variables:
$ id : int 1 2 3 4 5 6 7 8 9 10
$ new1: int [1:10, 1] 11 12 13 14 15 16 17 18 19 20
..- attr(*, "dimnames")=List of 2
.. ..$ : NULL
.. ..$ : chr "BLOB"
$ new2: int 201 202 203 204 205 206 207 208 209 210
所以您添加了一个仍然是矩阵的列。你可以看到嵌入矩阵保留了列名“BLOB”。将矩阵的一列分配给 data.frame 的列会更安全
dat[, "new1"] <- blob[,1]
发生这种情况的原因是 blob
可能有多个列。如果您只将它分配给“new1”,那么其他列应该放在哪里?因此它将整个矩阵嵌入列中。
你可以扩展嵌入矩阵
do.call("cbind.data.frame", dat)
这将保留“BLOB”列名称,但它现在将是一个“正常”data.frame,因此“BLOB”将列在 colnames()
当 R 打印带有嵌入矩阵的 data.frame 时,通常它会在矩阵列名前加上 data.frame 列名前缀,但当只有一列时,它只使用矩阵列名(诚然可以令人困惑)。观察:
mm<-matrix(1:9+10, nrow=3, dimnames=list(NULL, c("m1","m2","m3")))
data.frame(a=1:3, b = mm, c=letters[1:3])
# a b.m1 b.m2 b.m3 c
# 1 1 11 14 17 a
# 2 2 12 15 18 b
# 3 3 13 16 19 c
data.frame(a=1:3, b = mm[,1, drop=FALSE], c=letters[1:3])
# a m1 c
# 1 1 11 a
# 2 2 12 b
# 3 3 13 c
长话短说:不要将矩阵放入 data.frame。
关于r - 当 data.frame 获得新列时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40872034/