【问题标题】:data.table names character vector is a referencedata.table 名称字符向量是一个参考
【发布时间】:2014-03-29 16:49:27
【问题描述】:

如果您将 data.table 的名称存储在字符向量中,然后从 data.table 中删除一列,则我遇到了一个奇怪的“错误”(假设它没有记录在某处。)名称会相应地自动更新。我觉得这非常奇怪和违反直觉。这是一个错误吗?如果不是,原因是什么?

编辑:我在问是否返回当前名称的副本不是更好,而不是引用,这是容易出错的,并且更好地保留在具有真正性能优势的情况下(例如作为核心数据)。

> library(data.table)
data.table 1.8.8  For help type: help("data.table")
> sessionInfo()
R version 2.15.3 (2013-03-01)
Platform: x86_64-unknown-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=C                 LC_NAME=C                  LC_ADDRESS=C
[10] LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] data.table_1.8.8
> dt = data.table( a = 1:10, b = 1:10)
> cols = names(dt)
> cols
[1] "a" "b"
> dt[, a := NULL]
> cols
[1] "b"
>

【问题讨论】:

  • 你问的问题是......?
  • 对我来说更像是一个功能,尽管我不一定会预料到它。当您删除列时,cols 正在“交流”并得到更新,这似乎很有帮助。
  • data.table 包的一个核心原则是通过引用完成操作,并尽可能避免复制。这就是包裹如此之快的原因之一。如果您认为这是一个错误,那么您还没有理解该软件包。我知道这种行为一开始可能会令人惊讶,但您应该小心使用“bug”这个词。
  • 我了解 data.table 的核心原理,但在我看来,将 names() 返回的值作为参考是非常令人困惑的。这样做并没有提高性能,并且应该在真正需要它们时保留参考 - 实际数据。
  • This comment 应该对@Roland 的观点有所启发。 here's the relevant FR 这需要记录在案。我们只是还没有做到。如果您强烈认为它应该产生副本,那么开始对话的最佳位置是 data.table 邮件列表。

标签: r data.table


【解决方案1】:

当您定义cols 时,您将其绑定到dt:= 赋值操作员正在编辑dt,因此cols 相应更改。 R 用户通常不会处理此问题,因为大多数代码将变量重新定义(重新绑定)到新值,而不是编辑现有对象。例如,看下面的代码。

但是,正如@IShouldBuyABoat 所指出的,这是一项功能,而不是错误。实际上,在许多语言中都很典型。

> library(data.table)
> dt = data.table( a = 1:10, b = 1:10)
> dt  
     a  b
 1:  1  1
 2:  2  2
 3:  3  3
 4:  4  4
 5:  5  5
 6:  6  6
 7:  7  7
 8:  8  8
 9:  9  9
 10: 10 10
> cols = names(dt)
> cols
[1] "a" "b"
> dt = data.table(b = 1:10)
> dt  
     b
 1:  1
 2:  2
 3:  3
 4:  4
 5:  5
 6:  6
 7:  7
 8:  8
 9:  9
 10: 10
> cols
[1] "a" "b"

【讨论】:

  • 我的想法是,它应该返回当前名称的副本而不是引用,除非这样做有很大的性能提升(就像核心数据一样)。例如,如果你做了 dim(dt) 是一个副本,并且如果你做了 dim.dt = dim(dt),然后从 dt 中删除了一个列,则不会更新 dim.dt。这会导致不一致。
【解决方案2】:

您可以“复制”变量的名称。

library(data.table)
dt = data.table( a = 1:10, b = 1:10)
cols = copy(names(dt))
cols
dt[, a := NULL]
cols

【讨论】:

  • 复制名称比复制整个表格更好:copy(names(dt))
猜你喜欢
  • 2017-08-11
  • 1970-01-01
  • 2016-02-27
  • 2011-07-23
  • 2021-12-06
  • 2014-06-28
  • 2019-07-09
相关资源
最近更新 更多