r - 在 R 的 data.table 中按组查找行索引的最有效方法是什么?

标签 r performance indexing data.table

我正在处理一个大型数据表,需要按组查找行号。不幸的是,对数据表进行排序不是一个选项,因为它们在多个位置建立了索引(按 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/

相关文章:

r - 显示每列的唯一值

r - 将与时差对应的字符转换为以分钟为单位的数值

mysql - 求和/格查询的最佳索引策略

java - 为什么静态/成员变量比局部变量慢?

performance - 哪种迭代构造更适合在 Scala 中使用?

python - 如何将每个 x 个元素拆分一个列表并将这些 x 个元素添加到一个新列表中?

r - 在没有 for 循环的情况下更改数据框中多列的类

json - 使用json不配置Elasticsearch索引

elasticsearch - 使用ElasticSearch搜索时指定索引黑名单

R react 值 - 添加到列表中的唯一值