ant*_*nio 15 transpose r matrix
我今天得到了一个奇怪的结果.
要复制它,请考虑以下数据框:
x <- data.frame(x=1:3, y=11:13)
y <- x[1:3, 1:2]
Run Code Online (Sandbox Code Playgroud)
他们应该是,实际上是相同的:
identical(x,y)
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)
应用于 t()indentical对象应该产生相同的结果,但是:
identical(t(x),t(y))
# [1] FALSE
Run Code Online (Sandbox Code Playgroud)
不同之处在于列名:
colnames(t(x))
# NULL
colnames(t(y))
# [1] "1" "2" "3"
Run Code Online (Sandbox Code Playgroud)
鉴于此,如果您想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
Run Code Online (Sandbox Code Playgroud)
而:
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
Run Code Online (Sandbox Code Playgroud)
在后一种情况下, as.data.frame()找不到原始列名并自动生成它们.
罪魁祸首是as.matrix(),通过所谓t():
rownames(as.matrix(x))
# NULL
rownames(as.matrix(y))
# [1] "1" "2" "3"
Run Code Online (Sandbox Code Playgroud)
解决方法是设置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
Run Code Online (Sandbox Code Playgroud)
(并相应地重写 stack(...)调用.)
我的问题是:
为什么as.matrix()对待不同x和y与
你怎么能分辨出它们之间的区别?
请注意,其他信息功能不会揭示以下差异x, y:
identical(attributes(x), attributes(y))
# [1] TRUE
identical(str(x), str(y))
# ...
#[1] TRUE
Run Code Online (Sandbox Code Playgroud)
Konrad Rudolph对上述行为给出了简明但有效的解释( 更多细节见mt1022).
简而言之,康拉德表明:
一个)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
Run Code Online (Sandbox Code Playgroud)
可以通过更详细地检查对象找到原因:
> 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")
Run Code Online (Sandbox Code Playgroud)
请注意不同的row.names属性:
> .row_names_info(x)
[1] -3
> .row_names_info(y)
[1] 3
Run Code Online (Sandbox Code Playgroud)
从文档中我们可以收集到负数意味着自动的rownames(for x),而y行的名称不是自动的.并as.matrix以不同的方式对待它们.
| 归档时间: |
|
| 查看次数: |
206 次 |
| 最近记录: |