这似乎是一个微不足道的问题,我似乎无法找到解决方案:
考虑两个data.tables
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))
如何对dt
进行分组,其中dt1
告诉我需要分组的V1
分组的行号(id
)?
例如,结果将是
# id val
# 1: 1 20
# 2: 2 10
更新
对拟议解决方案进行快速基准测试
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
答案 0 :(得分:5)
另一种选择是使用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&gt; = 1.9.8中,.SD[val]
操作计划完全优化以使用GForce-所以紧紧抓住。
答案 1 :(得分:3)
一个选项是join
on
'id',然后执行子集
dt[dt1, on='id'][, .SD[1:.N==V1] ,id][,V1:=NULL][]
# id val
#1: 1 20
#2: 2 10