我很惊讶地做了以下事情:
R) system.time(lastOrder <- order[,lapply(.SD,tail,1),by="TRADER_ID,EXEC_IDATE"]);
utilisateur système écoulé
1.45 0.00 1.53
R) nrow(order)
[1] 75301
R) ncol(order)
[1] 23
认为这很长,然后我做了
R) system.time(lastOrder <- order[,list(test=tail(EXEC_IDATE,1)),by="TRADER_ID,EXEC_IDATE"]);
utilisateur système écoulé
0.14 0.00 0.14
据我了解,如果您知道要选择的所有行并且大部分工作都已完成,那么我不明白为什么将这个应用于所有列的时间应该延长10倍。我在第一段代码上做错了,这是我知道按组
选择最后一行的唯一方法答案 0 :(得分:6)
分组的最后一行:
DT[, .SD[.N], by="TRADER_ID,EXEC_IDATE"] # (1)
或更快(尽可能避免使用.SD
,以获得速度):
w = DT[, .I[.N], by="TRADER_ID,EXEC_IDATE"][[3]] # (2)
DT[w]
请注意,以下功能请求将使方法(1)与方法(2)一样快:
FR#2330 Optimize .SD[i] query to keep the elegance but make it faster unchanged.
答案 1 :(得分:3)
这样的事情怎么样? (合成数据意味着模仿我可以从问题中推断出你的内容)
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
tail
和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