【问题标题】:Why is `row.names` preferred over `rownames`?为什么 `row.names` 优于 `rownames`?
【发布时间】:2016-07-19 18:47:18
【问题描述】:

R 核心库中有两个函数。

  • row.names 获取和设置数据框的行名
  • rownames 检索或设置类似矩阵的对象的行名。

但是row.names 的文档指定对于数据框,“rownames”和“colnames”最终分别调用“row.names”和“names”,但首选后者。 为什么row.names 是首选吗?忽略row.names 直接调用rownames 不是更容易吗?

【问题讨论】:

  • 那个链接根本没有用。
  • @RichardScriven 如果这个问题得到了很好的答案,也许其他问题应该作为这个问题的副本关闭。
  • 谜题的一部分,我认为是“最终”这个词。由于rownames 最终会调用row.names 来获取data.frame,那么剪掉中间人并将其带到源头会更有效。我认为本文档关注 data.frames 的另一部分。
  • 请注意,“data.frame”具有明确的“row.names”属性,而不是“rownames”。此外,row.names 是一个通用函数,可以获取对象的这个特定属性,并且可以为类似于“data.frame”对象创建方法
  • 对我来说看起来像是交叉兼容性。 names(iris)colnames(iris) 都可以。我怀疑作者很友好地知道,对于来自 S 或早期 R 的老派程序员仍然可以使用旧功能,而新学校用户可以使用新功能。所以一段时间后该语言看起来有点像弗兰肯斯坦,但不必记住哪个函数与哪个数据类型相匹配是件好事。

标签: r


【解决方案1】:

row.names() 是 S3 通用函数,而 rownames() 是较低级别的非通用函数。 rownames() 实际上是 row.names() 的默认方法,在没有更具体方法的情况下应用于任何对象。

如果您在数据帧x 上进行操作,那么使用row.names(x) 效率更高,因为数据帧有一个特定的row.names() 方法。数据帧的row.names() 方法只是提取已经存储在x 中的"row.names" 属性。相比之下,由于rownames()的定义和函数之间的相互关系,rownames(x)必须提取x的所有维度名称,然后删除列名,然后与names(x)结合,然后删除names(x) 再次。此过程甚至涉及调用row.names(x) 作为中间步骤。这一切通常会发生得如此之快以至于您不会注意到它,但仅提取属性显然更有效。

一直使用通用版本row.names() 是合乎逻辑的,因为它总是调度适当的方法。 使用rownames(x) 而不是row.names(x) 并没有实际的进步。 对于定义了row.names 方法的对象类,rownames(x) 是错误的,因为它绕过了该方法。 对于没有定义 row.names 方法的对象类,那么这两个函数是等价的,因为row.names(x) 只是调用了rownames(x)

这两个函数存在的原因是历史性的。 rownames() 是较旧的函数,在引入泛型函数和方法之前是 R 语言的一部分。 它仅用于矩阵,但它适用于任何具有dimnames 属性的数据对象。 当x 是矩阵时,我个人使用rownames(x),否则使用row.names(x),但正如我所说,人们也可以一直使用row.names(x)

【讨论】:

  • 尚不清楚rownames()在哪些情况下增值(如果有的话)。
猜你喜欢
  • 1970-01-01
  • 2015-01-22
  • 2011-07-11
  • 2014-07-03
  • 2012-05-26
  • 2019-12-06
  • 2012-12-22
  • 1970-01-01
  • 2011-12-13
相关资源
最近更新 更多