我正在处理一个大型数据表,需要按组查找行号。不幸的是,对数据表进行排序不是一个选项,因为它们在多个位置建立了索引(按 id、时间等),因此我认为不能使用 setkey
。
解决这个问题最有效的方法是什么?
我目前已尝试过 which(...)
、k[...,which = TRUE]
和 k[, .I[。 ..]]
。有没有更快的方法?
通过基准测试,对于较小的数据表(少于 10 000 行),which(...)
似乎比 k[...,which = TRUE]
更有效,完整代码如下):
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
最佳答案
使用.I
,此选项返回一个包含两列的data.table
。第一列是 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
关于r - 在 R 的 data.table 中按组查找行索引的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71946874/