我正在處理一個大型資料表,需要按組查找行號。不幸的是,對資料表進行排序不是一種選擇,因為它們被索引了幾個地方(按 id、時間……),所以我認為setkey不能使用。
解決這個問題的最有效方法是什么?
我目前已經嘗試過which(...),k[..., which = TRUE]和k[, .I[...]]. 有沒有更快的方法?
通過基準測驗,which(...)似乎比較k[..., which = TRUE]小的資料表(少于 10 000 行,完整代碼如下)更有效:
test replications elapsed relative user.self sys.self
1 k[a == x, which = TRUE] 10 2.63 1.789 2.52 0.10
2 which(k$a == x) 10 1.47 1.000 1.47 0.00
3 setindex(k, a) 10 2.71 1.844 2.64 0.06
4 k[, .I[a == x]] 10 2.03 1.381 2.00 0.00
但隨著行數的增加,k[..., which = TRUE]速度會相當快:
> rbenchmark::benchmark(
"A" = {
k <- data.table(
a = sample(factor(seq_len(200)), size = 1000000, replace = TRUE)
)
u <- unique(k$a)
m <- lapply(u, function(x) k[a == x, which = TRUE])
},
"B" = {
k <- data.table(
a = sample(factor(seq_len(200)), size = 1000000, replace = TRUE)
)
u <- unique(k$a)
m <- lapply(u, function(x) which(k$a == x))
},
"C" = {
k <- data.table(
a = sample(factor(seq_len(200)), size = 1000000, replace = TRUE)
)
u <- unique(k$a)
setindex(k, a)
m <- lapply(u, function(x) k[a == x, which = TRUE])
},
"D" = {
k <- data.table(
a = sample(factor(seq_len(200)), size = 1000000, replace = TRUE)
)
u <- unique(k$a)
setindex(k, a)
m <- lapply(u, function(x) k[, .I[a == x]])
},
replications = 10,
columns = c("test", "replications", "elapsed",
"relative", "user.self", "sys.self"))
test replications elapsed relative user.self sys.self
1 A 10 3.64 1.000 3.61 0.08
2 B 10 43.22 11.874 42.73 0.02
3 C 10 3.70 1.016 3.72 0.04
4 D 10 46.71 12.832 46.33 0.03
uj5u.com熱心網友回復:
使用.I,此選項回傳data.table具有兩列的 a。第一列是 中的唯一值a,第二列是每個值出現在 中的索引串列k。表格與 OP 的不同m,但資訊都在那里,而且很容易訪問。
k[, .(idx = .(.I)), a]
基準測驗:
library(data.table)
k <- data.table(a = sample(factor(seq_len(200)), size = 1e6, replace = TRUE))
microbenchmark::microbenchmark(
A = {
u <- unique(k$a)
m <- lapply(u, function(x) k[a == x, which = TRUE])
},
B = {
m2 <- k[, .(idx = .(.I)), a]
},
times = 100
)
#> Unit: milliseconds
#> expr min lq mean median uq max neval
#> A 282.0331 309.2662 335.30146 325.3355 350.51080 525.7929 100
#> B 9.7870 10.3598 13.04379 10.8292 12.73785 65.4864 100
all.equal(m, m2$idx)
#> [1] TRUE
all.equal(u, m2$a)
#> [1] TRUE
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/464453.html
