今天我得到了一个奇怪的结果。移调相同的物体
要复制它,请考虑以下的数据帧:
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
:(并相应地重写stack(...)
调用)
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
我的问题是:
为什么
as.matrix()
对待不同x
和y
和你怎么能告诉他们有什么区别?
注意,其他信息功能不x, y
之间发现差异性:
identical(attributes(x), attributes(y))
# [1] TRUE
identical(str(x), str(y))
# ...
#[1] TRUE
评论到解决方案
Konrad Rudolph给出了一个简洁而有效的解释,上述行为(见mt1022 更多细节)。
总之康拉德表明:
一个)x
和y
是内部不同;
b)“identical
太简直太默认了”来捕捉这个内部差异。
现在,如果你把一组S
,其中有的S
,然后S
和T
所有元素的一个子集T
是完全一样的对象。所以,如果你把一个数据帧y
,其中有所有行和x
,然后x
和y
列应完全相同的对象。不幸的是x \neq y
!
这种行为不仅是违反直觉,而且是混淆的,也就是说差异不是不言自明,而只有内部甚至默认identical
函数看不到它。
另一个自然原理是转置两个相同的(类矩阵)对象产生相同的对象。再次,这是因为在转位之前,identical
是“过于宽松”的事实打破了;转置后,默认identical
足以看出差异。
恕我直言,这种行为(即使它是不是一个错误)是一个科学的语言如R.
希望这篇文章将推动一些关注和将R团队将考虑修改其错误行为。
似乎是如何定义'row.names',因为它们在'dput(x)'和'dput(y')中是不同的。在使用''[.data.frame'' – user20650
时可能会明确添加它们您可以使用dput(x)和dput(y),您将看到row.names以不同的方式存储。我认为它与自动row.names处理有关(查看https://stat.ethz.ch/R-manual/R-devel/library/base/html/row.names.html详细信息部分获取更多信息),不知道为什么子集返回不同的row.names尽管...说实话,它闻起来像一个意想不到的行为 – digEmAll
'相同(x,y,attrib.as.set = FALSE)'似乎在差异(注意到'*注意,相同的(x,y,FALSE,FALSE,FALSE,FALSE)会精确测试其是否相等。“* – user20650