Вот 2 сопоставимых (с точки зрения скорости) метода, использующих data.table
:
mtd0 <- function(DT) {
IDs <- DT[, unique(id)]
invisible(DT[, IDs <<- intersect(IDs, id), classification])
DT[id %in% IDs][order(classification, id, value)]
}
mtd1 <- function(DT) {
DT[DT[, .(id=Reduce(intersect, split(id, classification)))], on=.(id), nomatch=0L][
order(classification, id, value)]
}
Я думаю, что ваш id.list
сбил нас с толку, заставляя нас думать, что он был доступен как отдельная переменная, хотявы просто использовали его для создания MWE.
data:
library(data.table) #data.table_1.12.4
set.seed(0L)
nr <- 1e7
nclass <- 1e4
nid <- 1e2
dat <- data.table(classification=sample(nclass, nr, TRUE),
id=sample(nid, nr, TRUE))[, value := .I]
setorder(dat, classification, id, value)
тайминги от bench::mark(mtd0(dat), mtd1(dat))
:
# A tibble: 2 x 13
expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time result memory time gc
<bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm> <list> <list> <list> <list>
1 mtd0(DT) 810.17ms 810.17ms 1.23 897MB 3.70 1 3 810.17ms <df[,3] [6,197,991 x 3]> <df[,3] [80,334 x 3]> <bch:tm> <tibble [1 x 3]>
2 mtd1(DT) 1.33s 1.33s 0.752 854MB 3.01 1 4 1.33s <df[,3] [6,197,991 x 3]> <df[,3] [94,322 x 3]> <bch:tm> <tibble [1 x 3]>