最后按组对所有列data.table

时间:2013-01-03 16:42:18

标签: r data.table

我很惊讶地做了以下事情:

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倍。我在第一段代码上做错了,这是我知道按组

选择最后一行的唯一方法

2 个答案:

答案 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
相关问题