【问题标题】:Why do identical dataframes become different when changing rownames to the same将行名更改为相同时,为什么相同的数据框会变得不同
【发布时间】:2017-07-19 20:05:48
【问题描述】:

我在玩一些数据帧时遇到了一个奇怪的行为:当我创建两个相同的数据帧a,b,然后交换它们的行名时,它们的结果并不相同:

rm(list=ls())

a <- data.frame(a=c(1,2,3),b=c(2,3,4))
b <- a
identical(a,b)
#TRUE

identical(rownames(a),rownames(b))
#TRUE

rownames(b) <- rownames(a)

identical(a,b)
#FALSE

谁能重现/解释原因?

【问题讨论】:

  • 看起来行名最初是数字,但rownames() 返回一个字符向量,因此行名最终成为不同类型的属性。
  • 您可以检查结构,即c(NA, -3L)是第一个case更改为c("1", "2", "3")
  • 不要使用identical 来比较数据帧。使用all.equal(a,b) 告诉您名称不同。

标签: r dataframe rowname


【解决方案1】:

诚然,这有点令人困惑。从?data.frame 开始,我们看到:

如果 row.names 提供为 NULL 或未找到合适的组件 行名是从一开始的整数序列(以及这样的行 名称被认为是“自动的”,而不是由 as.matrix)。

所以最初ab 都有一个名为row.names 的整数属性:

> str(attributes(a))
List of 3
 $ names    : chr [1:2] "a" "b"
 $ row.names: int [1:3] 1 2 3
 $ class    : chr "data.frame"

但是rownames() 返回一个字符向量(dimnames() 也是如此,实际上是一个字符向量列表,在后台调用)。所以在重新分配你最终得到的行名之后:

> str(attributes(b))
List of 3
 $ names    : chr [1:2] "a" "b"
 $ row.names: chr [1:3] "1" "2" "3"
 $ class    : chr "data.frame"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-11
    相关资源
    最近更新 更多