【问题标题】:Column referencing: [[i]] vs [,i] for matrix, dataframe, and data.table列引用:[[i]] vs [,i] 用于矩阵、数据框和 data.table
【发布时间】:2016-11-10 20:24:11
【问题描述】:

有人可以向我解释一下matrixdata.framedata.table 在列引用方面的区别吗?我正在考虑每个类使用哪种语法,但我不明白它们如何/为什么不同。

取一个 10x10 的矩阵

foo <- matrix( nrow = 10, ncol = 10 )

我将仅填写第 2 列来演示:

foo[,2] <- rnorm(10)
head( foo, 3 )

        [,1]       [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
  [1,]   NA -0.4688874   NA   NA   NA   NA   NA   NA   NA    NA
  [2,]   NA -1.0273370   NA   NA   NA   NA   NA   NA   NA    NA
  [3,]   NA -0.3981627   NA   NA   NA   NA   NA   NA   NA    NA

现在我可以用foo[,2] 引用第二列,但foo[[2]] 只返回1 个单元格,在本例中为NA:

foo[,2]
 [1]  0.18340527  0.46511236 -2.43277107  0.13260218  0.20227436 -0.57518392 -0.62211864  2.00239088  -0.09561907  0.67536428

foo[[2]]
  [1] NA

如果我将矩阵更改为数据框,两种引用方法都有效:

foo <- data.frame( foo )
foo[,2]
  [1] -0.4688874 -1.0273370 -0.3981627 -0.2207062  0.5711004  1.1085851 -1.3343338  0.2337622  -1.0632469 -0.9783714


foo[[2]]
  [1] -0.4688874 -1.0273370 -0.3981627 -0.2207062  0.5711004  1.1085851 -1.3343338  0.2337622  -1.0632469 -0.9783714

现在,如果我转换为 data.table,则只有第二种方法有效,第一种方法返回值 2(根本不在表中):

foo[,2]
  [1] 2
foo[[2]]
  [1] -0.4688874 -1.0273370 -0.3981627 -0.2207062  0.5711004  1.1085851 -1.3343338  0.2337622  -1.0632469 -0.9783714

所以我的问题是,为什么不同的类有不同的语法?是否有适用于所有 3 个类的特定语法,或者我们是否需要在知道如何调用引用之前知道/检查表格类?

编辑:这里也很有趣的是行引用在类之间更加一致。

分别针对matrix、dataframe、data.table:

foo[2,]
 [1]        NA 0.4651124        NA        NA        NA        NA        NA        NA        NA        NA

foo <- data.frame( foo )
foo[2,]
  X1        X2 X3 X4 X5 X6 X7 X8 X9 X10
2 NA 0.4651124 NA NA NA NA NA NA NA  NA

setDT( foo )
foo[2,]
  X1        X2 X3 X4 X5 X6 X7 X8 X9 X10
1: NA 0.4651124 NA NA NA NA NA NA NA  NA

【问题讨论】:

  • 您说得很好,尽管我很喜欢使用 R,但矩阵、data.frame 和 data.table 类型之间的单元格引用缺乏一致性令人沮丧,尤其是对于新用户而言。而且您甚至还没有列出清单……或者是吗? ;)
  • ?"[["?"["?"[.data.frame" 中有大量信息。你看了吗?至于data.table 语法,据我所知,这纯粹是其主要作者的设计决定。另请注意,矩阵只是具有维度属性的向量,而 data.frame 基本上是list
  • 当涉及到不同数据类型的引用时,我发现 Hadley Wickham 的书“Advanced R”解释得很好。但是,它不涉及data.tables
  • “类”中使用的每个函数也都有各自的方法。某些类的print 方法重合(即“矩阵”、“data.frame”、“data.table”look 相似)这一事实并不意味着它们也将/ should/are-built-to 行为类似。您可以自己创建一个类似“矩阵”的类并定义/记录基本的 [[&lt;- 方法,这些方法将适合您的类。
  • @rosscova 所有这些实际上都是函数本身。

标签: r matrix dataframe data.table


【解决方案1】:

自从在此处发布此问题后,我学到了一些东西(在评论者的大力帮助下!),这有助于我理解我提到的差异。如果有人可以澄清我在这里遇到的任何问题,我将不胜感激:

  • matrixdata.framedata.table 类的对象实际上都是 list 对象,但它们在一个重要方面有所不同。

  • data.framedata.table 对象的每一列都是“在其内部”列表的一个元素,这意味着可以以与列表元素相同的方式提取列,因此 @ 987654327@ 非常适合调用这两个类中的第二列。

  • matrix 的不同之处在于每个 单元格 都是列表的一个元素,这意味着 foo[[2]] 只会检索一个单元格,而不是一列(这让我们知道。 ..).

  • 构成matrix 的那些列表项是按列“填充”的(从上到下,从左到右),因此调用foo[[2]] 正在检索第二项,这里位于第 1 列的第 2 行。

  • 由于matrix 也有维度,因此foo[,2] 被接受为引用第二列,就像data.frame 对象一样。

  • data.table 对象(直到最近,请参阅下一点)对调用 foo[,2] 没有特别合乎逻辑的响应,并返回值 2,而不管它是什么数据参考,我找不到很好的理由。

  • 1234563导致我的问题的困惑已被取代!

总之:

  1. 我在问题中提到的所有对象实际上都是列表(这意味着我现在在 cmets 中得到了 @N8TRO 的笑话,我之前天真地忘记了),data.tabledata.frame 都包含每个列都有一个列表元素,以及一个包含每个单元格的列表元素的matrix(这使得[[ 调用现在对我有意义)。

  2. 所有提到的对象都有维度,这意味着(截至最近的data.table 包更新)foo[,2] 语法对所有 3 个类都有效。耶!

非常感谢评论者为我指出正确的方向(并让我现在得到的笑话)。我希望这可以帮助将来遇到与我相同的困惑的人。

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 2016-07-08
    • 2012-01-16
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多