【问题标题】:Why does data.table change the key after a transformation in j?为什么data.table在j中转换后会更改键?
【发布时间】:2014-03-18 15:10:19
【问题描述】:

我有一个带有两列键(id、日期)和一列或多列数据的 data.table。某些数据可能缺少值,因此我使用 zoo 的 na.locf() 来填充它。我注意到此操作更改了我的 data.table 中的键,我需要为后续连接重新键入它。为什么会发生这种情况,在哪些其他情况下我可以期待这种行为?

您可以使用下面的代码重现该问题。

谢谢!

require(zoo)
d <- data.table(id = rep(1:2, each = 5), date = rep(1:5, 2), value = c(1,2,NA,NA,NA, 6,7,8,9,10))
setkey(d, id, date)
x <- d[, lapply(.SD, na.locf, na.rm = FALSE, maxgap = 1), by = 'id']

key(d)
key(x)

【问题讨论】:

  • 那么,data.table 怎么知道新的date 列仍然是排序的呢?我发现更令人惊讶的是d[, names(d)[-1] := lapply(.SD, na.locf, na.rm = FALSE, maxgap = 1), by = 'id'] 完全删除了密钥。
  • 我认为默认行为是通过键中的列重新设置密钥,只是想确保它不是发生了其他事情。
  • 不,列是键意味着data.table是按它排序的。如果您创建一个新列(无论是您的方式还是通过引用),这意味着它不确定 data.table 是否按它排序。您必须明确地重新键入是一项功能,因为排序会降低性能,并且有时您不希望 data.table 使用新列作为键,即使它的名称与旧列的名称相同。

标签: r data.table


【解决方案1】:

我认为这是你想要的:

x <- copy(d)
x[, (3:length(x)) := lapply(.SD, na.locf, maxgap = 1), by = 'id', .SDcols=3:length(x)]
key(x)

结果:

[1] "id"   "date"

还有x

    id date value
 1:  1    1     1
 2:  1    2     2
 3:  1    3     1
 4:  1    4     2
 5:  1    5     1
 6:  2    1     6
 7:  2    2     7
 8:  2    3     8
 9:  2    4     9
10:  2    5    10

这假设您不需要将na.locf 应用于date 列。由于您没有在其他列上使用 := 更改该列,因此保留了表上的键。

另外,我必须将您对 na.locf na.rm 的使用更改为默认值,否则不会做任何事情。

【讨论】:

    猜你喜欢
    • 2020-02-15
    • 2014-06-21
    • 2012-03-09
    • 1970-01-01
    • 2018-10-16
    • 2022-01-22
    • 2022-11-21
    • 2020-07-24
    • 1970-01-01
    相关资源
    最近更新 更多