这个怎么样?(合成数据,旨在模拟我从问题中推断出的有关您的数据)
tmp <- data.table(id = sample(1:20, 1e6, replace=TRUE),
date = as.Date(as.integer(runif(n=1e6, min = 1e4, max = 1.1e4)),
origin = as.Date("1970-01-01")),
data1 = rnorm(1e6),
data2 = rnorm(1e6),
data3 = rnorm(1e6))
> system.time(X <- tmp[, lapply(.SD, tail, 1), by = list(id, date)])
user system elapsed
1.95 0.00 1.95
> system.time(Y <- tmp[, list(tail(data1, 1)), by = list(id, date)])
user system elapsed
1.24 0.01 1.26
> system.time({
setkey(tmp, id, date)
Z <- tmp[unique(tmp)[, key(tmp), with=FALSE], mult="last"]
})
user system elapsed
0.90 0.02 0.92
在确保相同的顺序之后,X和Z是相同的:
> identical(setkey(X, id, date), setkey(Z, id, date))
[1] TRUE
我的
lapply
和 1 列的
tail
的区别并不像你的那么大,但是如果没有数据结构,很难说更多。此外,请注意,这种方法中大部分时间都用于设置键。如果表已经按分组列排序,则速度非常快:
> system.time(Z <- tmp[unique(tmp)[, key(tmp), with=FALSE], mult="last"])
user system elapsed
0.03 0.00 0.03
或者,您可以使用临时列将许多列问题转换为1列问题进行翻译:
> system.time({
tmp[, row.num := seq_len(nrow(tmp))]
W <- tmp[tmp[, max(row.num), by = list(id, date)]$V1][, row.num := NULL]
tmp[, row.num := NULL]
})
user system elapsed
0.92 0.00 1.09
> identical(setkey(X, id, date), setkey(W, id, date))
[1] TRUE
w = DT[, list(IDX=.I[.N]), by="TRADER_ID,EXEC_IDATE"]$IDX
和DT[w]
。 - statquant