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的引用
如何控制它返回第1行,第2行,第n行,而不是默认为最后一行?
不优雅,但有点工作:
n = 3L
dt1[, v := dt2[.SD, on=.(id), x.letter[n], by=.EACHI]$V1]
Run Code Online (Sandbox Code Playgroud)
一些问题:
它没有选择使用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)如果n在1:.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)
我能想到的最灵活的想法是只加入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.