将继承范围与 data.table 中的 by 连接起来

Posted

技术标签:

【中文标题】将继承范围与 data.table 中的 by 连接起来【英文标题】:Join inherited scope with by in data.table 【发布时间】:2014-09-04 23:31:46 【问题描述】:

我在 data.table 1.9.3 上,也许我错了,但我不记得 以下是之前预期的。

我构建了 2 个 data.tables,dta 和 dtb

> dta
   idx vala fdx
1:   1    2   a
2:   2    4   a
3:   3    6   b

> dtb
   idx valb
1:   1    3
2:   4    6

> dput(x = dta)
structure(list(idx = c(1, 2, 3), vala = c(2, 4, 6), fdx = c("a",
"a", "b")), .Names = c("idx", "vala", "fdx"), row.names = c(NA,
-3L), class = c("data.table", "data.frame"), .internal.selfref =
<pointer: 0x0000000000110788>, sorted = "idx")

> dput(x = dtb)
structure(list(idx = c(1, 4), valb = c(3, 6)), .Names = c("idx",
"valb"), row.names = c(NA, -2L), class = c("data.table", "data.frame"
), .internal.selfref = <pointer: 0x0000000000110788>, sorted = "idx")

在这两种情况下,键都是 idx。

以下的作品,当然

> dta[dtb, sum(valb)]
[1] 9

但事实并非如此

> dta[dtb, sum(valb), by = fdx]
Error in `[.data.table`(dta, dtb, sum(valb), by = fdx) :
  object 'valb' not found

但这确实

> dta[dtb][, sum(valb), by = fdx]
   fdx V1
1:   a  3
2:  NA  6

如果我们看到中间步骤

> dta[dtb]
   idx vala fdx valb
1:   1    2   a    3
2:   4   NA  NA    6

我早就料到了

dta[dtb, sum(valb), by = fdx] == dta[dtb][, sum(valb), by = fdx]

我哪里出错了?

【问题讨论】:

将此问题归档为FR #733。还提交了相关的FR #732。谢谢。 我也可以在 data.table 1.9.4 中重现这种行为(= 错误?),有什么消息吗? 【参考方案1】:

只是猜测

library(data.table)

dta <- data.frame(idx=c(1,2,3), 
                  vala=c(2,4,6),
                  fdx=c('a','a','b'))
dta <- data.table(dta)

dtb <- data.frame(idx=c(1,4),
                  valb=c(3,6))
dtb <- data.table(dtb)

setkey(dta,idx)
setkey(dtb,idx)

所以当你打电话时

dta[dtb, sum(valb)]

有点像打电话

tmp <- dta[dtb]
attach(tmp)
sum(valb)
detach(tmp)

但是,如果你打电话

dta[dtb, sum(valb), by=fdx]

这有点像打电话

tmp <- dta[dtb]
# attach(tmp) : attach doesn't happen
sum(valb)
# detach(tmp) : detach doesn't happen

函数不知道如何处理附加参数。例如,这也会引发错误:

dta[dtb, class(fdx), sum(valb)]

但是,这行得通

dta[dtb][, sum(valb), by=fdx]

有点像

tmp <- dta[dtb]
tmp[, sum(valb), by=fdx]

就像我说的,这只是对为什么函数可能无法按预期工作的猜测。

【讨论】:

以上是关于将继承范围与 data.table 中的 by 连接起来的主要内容,如果未能解决你的问题,请参考以下文章

如何理解data.table中。()的含义

R语言data.table导入数据实战:data.table使用by函数进行数据分组(aggregate)

使用 data.table[,,by=...] 时包括所有排列

是否可以将 Spark 中的 data.table 与 Spark Dataframes 一起使用?

将 data.table 列与数值列中的 NA 进行比较

R语言data.table导入数据实战:data.table使用by函数进行数据分组(aggregate)并获取分组的第一个数值或者最后一个数值