R 给定每个组的行索引的data.table子集

R 给定每个组的行索引的data.table子集,r,data.table,R,Data.table,这似乎是一个微不足道的问题,我似乎无法找到解决方案: 考虑两个数据表 library(data.table) dt <- data.table(id = c(1,1,1,2,2,2), val = c(10,20,30,10,20,30)) dt1 <- data.table(id = c(1,2), V1 = c(2,1)) 更新 对建议的解决方案进行快速的基准测试 library(data.table)

这似乎是一个微不足道的问题,我似乎无法找到解决方案:

考虑两个
数据表

library(data.table)
dt <- data.table(id = c(1,1,1,2,2,2),
                 val = c(10,20,30,10,20,30))

dt1 <- data.table(id = c(1,2),
                  V1 = c(2,1))

更新

对建议的解决方案进行快速的基准测试

library(data.table)
s <- 100000
set.seed(123)
dt <- data.table(id = rep(seq(1:s), each=10),
                 val = rnorm(n = s*10, 0, 1))

dt1 <- data.table(id = seq(1:s),
                  V1 = sample(1:10, s, replace=T))


library(microbenchmark)

microbenchmark(

  akrun = { dt[dt1, on='id'][, .SD[1:.N==V1] ,id] },

  david = { dt[dt1, val[i.V1], on = 'id', by = .EACHI] },

  symbolix = { dt[, id_seq := seq(1:.N), by=id][dt1, on=c(id_seq = "V1", "id") , nomatch=0] },

   times = 5

 )
#Unit: milliseconds
#     expr         min          lq        mean      median          uq         max neval
#    akrun 17809.51370 17887.89037 18005.32357 18043.80279 18130.78978 18154.62118     5
#    david    48.17367    53.76436    53.79004    54.69096    55.59657    56.72467     5
 #symbolix   507.67312   511.23492   562.59743   571.31160   579.61228   643.15525     5
库(data.table)

一个选项是在
'id'上加入
,然后执行子集

dt[dt1, on='id'][, .SD[1:.N==V1] ,id][,V1:=NULL][]
#   id val
#1:  1  20
#2:  2  10

另一个选项是使用
by=.EACHI
,以便在连接时子集
val

dt[dt1, val[i.V1], on = 'id', by = .EACHI]
#    id V1
# 1:  1 20
# 2:  2 10
如果有更多的列,可以使用
.SD[i.V1]



作为旁注,在data.table v>=1.9.8中,计划对
.SD[val]
操作进行充分优化,以使用GForce-因此请抓紧。

在类似的主题上,然后,也许
dt[,id_seq:=seq(1.N),by=id][dt1,On=c(id_seq=“V1”,“id”),nomatch=0]
(以避免
.SD
分配)那么,
.SD
是否已经在1.9.7中进行了优化?我很困惑。@docendodiscimus它针对显式使用正整数(如
.SD[2L]
)的情况进行了优化,但如果将其作为变量传递(如
val),则未进行优化。非常好。我一直在努力解决
.EACHI
问题,所以我很高兴看到这一点!
dt[dt1, val[i.V1], on = 'id', by = .EACHI]
#    id V1
# 1:  1 20
# 2:  2 10