更新多行连接

Sym*_*xAU 11 r data.table

在执行update-join时,i表中每个键有多行,如何控制返回哪一行?

在此示例中,update-join返回最后一行 dt2

library(data.table) 

dt1 <- data.table(id = 1) 
dt2 <- data.table(id = 1, letter = letters) 

dt1[ 
    dt2 
    , on = "id" 
    , letter := i.letter 
    ] 

dt1
#    id letter
# 1:  1      z
Run Code Online (Sandbox Code Playgroud)

如何控制它返回第1行,第2行,第n行,而不是默认为最后一行?


参考

一些类似于用户@Frank的引用

Fra*_*ank 6

如何控制它返回第1行,第2行,第n行,而不是默认为最后一行?

不优雅,但有点工作:

n = 3L
dt1[, v := dt2[.SD, on=.(id), x.letter[n], by=.EACHI]$V1]
Run Code Online (Sandbox Code Playgroud)

一些问题:

  1. 它没有选择使用GForce,例如,如下所示:

    > dt2[, letter[3], by=id, verbose=TRUE]
    Detected that j uses these columns: letter 
    Finding groups using forderv ... 0.020sec 
    Finding group sizes from the positions (can be avoided to save RAM) ... 0.000sec 
    lapply optimization is on, j unchanged as 'letter[3]'
    GForce optimized j to '`g[`(letter, 3)'
    Making each group and running j (GForce TRUE) ... 0.000sec 
       id V1
    1:  1  c
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果n1:.N某些已加入的组之外,则不会发出警告:

    n = 40L
    dt1[, v := dt2[.SD, on=.(id), x.letter[n], by=.EACHI]$V1]
    
    Run Code Online (Sandbox Code Playgroud)

或者,养成检查i更新连接x[i]是否被连接列"键入" 的习惯:

cols = "id"
stopifnot(nrow(dt2) == uniqueN(dt2, by=cols))
Run Code Online (Sandbox Code Playgroud)

然后根据需要创建一个不同的i表来加入

mDT = dt2[, .(letter = letter[3L]), by=id]
dt1[mDT, on=cols, v := i.letter]
Run Code Online (Sandbox Code Playgroud)


the*_*ail 6

我能想到的最灵活的想法是只加入dt2包含你想要的行的部分.所以,对于第二行:

dt1[ 
    dt2[, .SD[2], by=id]
    , on = "id" 
    , letter := i.letter
    ]

dt1
#   id letter
#1:  1      b
Run Code Online (Sandbox Code Playgroud)

使用@Frank的帽子提示来简化子选择dt2.