【问题标题】:What can a data frame do that a tibble cannot?数据框能做什么而 tibble 不能?
【发布时间】:2021-03-03 23:55:27
【问题描述】:

Tidyverse 的粉丝经常给出使用 tibbles 而不是数据框的几个优点。它们中的大多数似乎旨在保护用户免于犯错。例如,与数据帧不同的是,tibbles:

  • 不需要,drop=FALSE 参数即可不从数据中删除维度。
  • 不会让$ 运算符对列名进行部分匹配。
  • 仅当输入向量的长度正好为 1 时才回收它们。

我逐渐确信将我所有的数据框都替换为 tibbles。这样做的主要缺点是什么?更具体地说,数据框可以做什么而 tibble 不能?

首先,我想明确表示我不是在询问data.table 或对 Tidyverse 的任何宏观反对意见。我严格要求 tibbles 和数据框。

【问题讨论】:

  • Tibbles 是数据框 - 它们有 data.frame 类,只是带有其他方法。因此,与其说数据框有什么不同,不如说 tibble 如何修改数据框的行为。差异在tibbles vignette 中捕获。个人认为修改后的print方法是最有用的功能。
  • 不是一个答案,而是关于 R-package-devel 的一个很长的有趣线程,其中有几个 R 权威讨论了 tibbles 的一些含义:tibbles are not data frames。无论如何,Jim Lemon 将老虎纳入综合格斗比赛的比喻值得一读。
  • @Henrik 当然读起来很有趣,但总结似乎很简单,就像“小标题违反了 Liskov 替换原则”。
  • 虽然“不推荐使用 [ 使用逻辑或 2 列整数矩阵 i 对 [data.frame] x[i] 进行矩阵索引” (?[.data.frame)方便(例如herehere)。似乎这种索引不能在小标题上使用。 tb = tibble(x = 1:3, y = 4:6); m = cbind(c(3, 2), c(2, 1)); tb[m]; df = as.data.frame(tb); df[m]
  • 我发现 tibbles 缺少的一件事是行名。虽然这是设计使然,但在计算距离时有时会有点烦人。使用tibble::column_to_rownames() 确实有效,但将类型更改回data.frame

标签: r dataframe tibble


【解决方案1】:

来自the trouble with tibbles,您可以阅读:

小标题真的没有任何问题

然而,

一些较旧的包不能使用 tibbles,因为它们的替代子集方法。他们期望 tib[,1] 返回一个向量,而实际上它现在将返回另一个小标题。

这是@Henrik 在 cmets 中指出的。

例如,length 函数不会返回相同的结果:

library(tibble)
tibblecars <- as_tibble(mtcars)
tibblecars[,"cyl"]
#> # A tibble: 32 x 1
#>      cyl
#>    <dbl>
#>  1     6
#>  2     6
#>  3     4
#>  4     6
#>  5     8
#>  6     6
#>  7     8
#>  8     4
#>  9     4
#> 10     6
#> # ... with 22 more rows
length(tibblecars[,"cyl"])
#> [1] 1
mtcars[,"cyl"]
#>  [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
length(mtcars[,"cyl"])
#> [1] 32

其他例子:

Invariants for subsetting and subassignment 解释了tibble 的行为与data.frame 的不同之处。

已知这些限制,Hadley 在interacting with legacy code 中给出的解决方案是:

少数函数不适用于 tibbles,因为它们希望 df[, 1] 返回一个向量,而不是一个数据帧。如果遇到这些函数之一,请使用 as.data.frame() 将 tibble 转回数据框:

【讨论】:

  • 还有一个例子here
  • length 是您所指出的一个例子,这一事实似乎并不明显。您的措辞方式听起来像是 length 函数有问题,很容易被愚弄以为这是一些 S3 诡计。真正发生的事情以及您试图展示的是length 返回1,因为它给出了标题tibblecars[,"cyl"] 中的列数,这是一,而length(mtcars[,"cyl"]) 是32,因为mtcars[,"cyl"]是 32 个元素的向量 - 不是数据框。简而言之,length 的行为是正确的……在错误的数据上。
  • 我没有说长度有问题,它只是根据对象类型(数据框或小标题)返回另一个结果,这可能会导致使用它的包出错。
【解决方案2】:

在这里学习:https://cran.r-project.org/web/packages/tibble/vignettes/tibble.html

tibble 和数据帧之间存在三个主要区别:

  • 打印
  • 子集
  • 回收规则

小标题:

  • 永远不要更改输入的类型(即,不再有 stringsAsFactors = 错误!)
  • 永远不要调整变量的名称
  • 懒惰地和顺序地评估参数
  • 永远不要使用 row.names()
  • 仅回收长度为 1 的向量

大数据帧显示尽可能多的行,直到内存缓冲区不堪重负。在这种情况下,R 将在数据帧的任意部分停止。

在 tibble 格式中,仅显示前十行和所有合适的列。 还会显示数据集的列数据类型和大小。

【讨论】:

  • 这是一个好的开始,但我认为数据框能做的 tibble 不能做的不是列出两种数据类型之间的差异,而是列出这些数据类型的后果差异。
猜你喜欢
  • 2011-08-23
  • 2018-05-30
  • 2010-11-24
  • 2016-05-28
  • 1970-01-01
  • 2016-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多