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