我今天得到了一个奇怪的结果。
要复制它,请考虑以下数据框:
x <- data.frame(x=1:3, y=11:13)
y <- x[1:3, 1:2]
它们应该并且实际上是相同的:
identical(x,y)
# [1] TRUE
申请
t()
相同的对象应该产生相同的结果,但是:identical(t(x),t(y))
# [1] FALSE
不同之处在于列名:
colnames(t(x))
# NULL
colnames(t(y))
# [1] "1" "2" "3"
鉴于此,如果您想堆叠
y
按列,你会得到你所期望的:stack(as.data.frame(t(y)))
# values ind
# 1 1 1
# 2 11 1
# 3 2 2
# 4 12 2
# 5 3 3
# 6 13 3
尽管:
stack(as.data.frame(t(x)))
# values ind
# 1 1 V1
# 2 11 V1
# 3 2 V2
# 4 12 V2
# 5 3 V3
# 6 13 V3
在后一种情况下,
as.data.frame()
找不到原始列名并自动生成它们。罪魁祸首在
as.matrix()
,由 t()
调用:rownames(as.matrix(x))
# NULL
rownames(as.matrix(y))
# [1] "1" "2" "3"
解决方法是设置
rownames.force
:rownames(as.matrix(x, rownames.force=TRUE))
# [1] "1" "2" "3"
rownames(as.matrix(y, rownames.force=TRUE))
# [1] "1" "2" "3"
identical(t(as.matrix(x, rownames.force=TRUE)),
t(as.matrix(y, rownames.force=TRUE)))
# [1] TRUE
(并重写
stack(...)
相应地调用。)我的问题是:
as.matrix()
区别对待 x
和 y
和 请注意,其他信息函数不会显示
x, y
之间的差异。 :identical(attributes(x), attributes(y))
# [1] TRUE
identical(str(x), str(y))
# ...
#[1] TRUE
对解决方案的评论
Konrad Rudolph对上述行为给出了简洁而有效的解释(另见 mt1022
更多细节)。
简而言之,康拉德表明:
a)
x
和 y
内在不同;b) “
identical
默认情况下太松懈了”,无法捕捉到这种内部差异。现在,如果你取一个子集
T
套装 S
,它具有 S
的所有元素,然后 S
和 T
是完全相同的对象。所以,如果你拿一个数据框 y
,其中包含 x
的所有行和列,然后 x
和 y
应该是完全相同的对象。不幸的是x \neq y
!这种行为不仅违反直觉,而且令人困惑,即差异不是不言而喻的,而只是内部的,甚至是默认的
identical
函数看不到。另一个自然原则是转置两个相同(类似矩阵)的对象会产生相同的对象。同样,这被以下事实打破:在转置之前,
identical
是“太松懈”;转置后,默认identical
足以看出区别。恕我直言,这种行为(即使它不是错误)对于像 R 这样的科学语言来说是一种不当行为。
希望这篇文章能引起一些关注,R 团队会考虑修改它。
最佳答案
identical
默认情况下太宽松了,但您可以更改它:
> identical(x, y, attrib.as.set = FALSE)
[1] FALSE
通过更详细地检查对象可以找到原因:
> dput(x)
structure(list(x = 1:3, y = 11:13), .Names = c("x", "y"), row.names = c(NA,
-3L), class = "data.frame")
> dput(y)
structure(list(x = 1:3, y = 11:13), .Names = c("x", "y"), row.names = c(NA,
3L), class = "data.frame")
注意不同的
row.names
属性:> .row_names_info(x)
[1] -3
> .row_names_info(y)
[1] 3
从文档中我们可以收集到负数意味着自动行名(对于
x
),而 y
的行名称不是自动的。和 as.matrix
区别对待他们。
关于r - 转置相同的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43209857/