如何进行X [Y] data.table连接,而不会丢失X上的现有主键?

Dou*_*ark 6 r data.table

当使用X [Y]连接data.tables X和Y时,X必须有一个键,Y的键用来进行连接.如果X是一个非常大的表并且通常键入未在连接中使用的列,则需要为连接更改X的键,然后在连接后恢复为原始键.有没有一种有效的方法来进行连接,而不会丢失X上的原始主键?

我有一个大的时间序列环境数据集DT(1M行,36列),作为data.table,在站点和日期列上有键.我需要对DT中的现有列进行计算和/或使用小型查找或重新编码表基于现有列插入新列.

这是一个最小的例子:

require(data.table)   # using v1.9.5

# main data table DT, keyed on site and date, with data column x
DT <- data.table(site = rep(LETTERS[1:2], each=3),
                 date = rep(1:3, times=2),
                 x = rep(1:3*10, times=2),
                 key = "site,date")
DT
#    site date  x
# 1:    A    1 10
# 2:    A    2 20
# 3:    A    3 30
# 4:    B    1 10
# 5:    B    2 20
# 6:    B    3 30

# lookup table for x to y lookup, keyed on x
x2y <- data.table(x = c(10,20), y = c(100,200), key = "x")
x2y
#     x   y
# 1: 10 100
# 2: 20 200
Run Code Online (Sandbox Code Playgroud)

要将查找表x2y与主表DT连接,我将DT键设置为"x":

setkey(DT,x)
Run Code Online (Sandbox Code Playgroud)

然后连接按预期工作.

DT[x2y]
#    site date  x   y
# 1:    A    1 10 100
# 2:    B    1 10 100
# 3:    A    2 20 200
# 4:    B    2 20 200
Run Code Online (Sandbox Code Playgroud)

我可以在计算中使用查找表中的"y"或在DT中创建一个新列.

DT[x2y, y:=y]
#    site date  x   y
# 1:    A    1 10 100
# 2:    B    1 10 100
# 3:    A    2 20 200
# 4:    B    2 20 200
# 5:    A    3 30  NA
# 6:    B    3 30  NA
Run Code Online (Sandbox Code Playgroud)

但现在我的时间序列数据集DT键入"x",我需要将密钥设置回"site,date"以供进一步使用.

setkey(DT,site,date)
Run Code Online (Sandbox Code Playgroud)

当DT非常大(1M行)时,这种方法(键X,连接,然后重新键X)是最快的方法,或者是否有同样有效的方式来执行此类查找连接,而不会丢失原始方法关键在大DT桌上?

Fra*_*ank 7

更新:由于修复了错误,因此不再需要.请参阅接受的答案.


我会加入x:

DT[,y:=x2y[J(DT$x)]$y]
Run Code Online (Sandbox Code Playgroud)

关键DT是保留在这里.

  • 谢谢,这对我有用.正如Arun所提到的,当实现二级密钥的连接时,我期待更简单,更直观的语法.. (2认同)
  • 对于2 x 1e6随机排序的DT数据集,我刚刚检查了这个答案与我的OP的时间关系.OP方法(setkey,join,setkey)需要522 ms,这个答案需要251 ms.所以它的速度是我的OP方法的两倍.我也尝试将set2key(DT,x)添加到这个答案的方法中,它花了426毫秒,这意味着set2key没有帮助,在目前的data.table 1.9.5. (2认同)

Aru*_*run 4

实施辅助密钥(自 v1.9.6 起)以及最近正确保留/丢弃密钥的错误修复(在 v1.9.7 中)后,您现在可以使用以下命令执行此操作on=

# join
DT[x2y, on="x"] # key is removed as row order gets changed.

# update using joins
DT[x2y, y:=y, on="x"] # key is retained, as row order isn't changed.
Run Code Online (Sandbox Code Playgroud)