【发布时间】:2018-04-19 10:20:02
【问题描述】:
让我们将我要分配到的表称为 dta,并将我要加入和聚合到 dta 的数据的源称为 dts。
dta = data.table(i=1:4, x=rnorm(4))
dts = data.table(i=rep(1:3, each=3), z=runif(9))
我认为我应该能够加入“i”并在一个语句中对其进行汇总:
dta[dts, z_sum := sum(i.z), by=i, on='i']
可惜,这行不通
Error in `[.data.table`(dta, dts, `:=`(z_sum, sum(i.z)), by = i, on = "i") :
object 'i.z' not found
Enter a frame number, or 0 to exit
1: dta[dts, `:=`(z_sum, sum(i.z)), by = i, on = "i"]
2: `[.data.table`(dta, dts, `:=`(z_sum, sum(i.z)), by = i, on = "i")
将by=i 替换为by=.EACHI 会得到错误的结果(dts 中z 的最后一个值是i 变量的每个值)
并且完全省略by 只是将所有值相加dts$z 并将相同的值分配给dta 中的所有行。
现在,我可以做到了:
dta[dts[, .(z=sum(z)), keyby=i], z := i.z, on='i']
但似乎应该有某种方式与 data.table 内部交互,以便在一个有效的语句中实现这一点,而不是单独的聚合,然后在这里完成连接。
我是否遗漏了什么,或者这是做事的最佳方式?我正在执行非常大的连接(将具有数亿行的表合并数千次),因此能够充分利用我所能达到的所有效率非常重要。
【问题讨论】:
-
是的,这行得通,但这可能比我在上一个代码 sn-p 中概述的两步过程更有效吗?
-
我猜它们都或多或少相同,只是你正在修改原始对象
-
我猜当 dta 更大幅度地对 dts 进行子集化时,可以通过首先用 dta 对 dts 进行子集化,聚合,然后再加入,就像你所做的那样,可以避免一些计算。一个似乎有意义的例子。似乎有一个假设,即 i data.table 小于 x,这让我感到惊讶。感谢您的快速回复!
标签: r data.table split-apply-combine