我正在处理一个 Big Data 表,需要按组查找行号.不幸的是,对数据表进行排序不是一个选项,因为它们被索引到多个位置(按id、时间等)所以我认为setkey不能用.

What is the most efficient way to approach this problem?

我目前试过which(...)k[..., which = TRUE]k[, .I[...]].有没有更快的办法?

通过基准测试,对于较小的数据表(少于which(...)00行,完整代码如下),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相关问答推荐

在之前合并的数据.tables中分配新列后.internal.selfref无效

有没有一种方法可以在子包上使用‘library()’中的‘exclub’参数?

R中的枢轴/转置

根据固定值范围在tible中添加新行

使用预定值列表将模拟数量(n)替换为rnorm()

在不安装软件包的情况下测试更新

在GGPLATE中将突出的点放在前面

为什么当用osmdata映射R时会得到相邻状态?

对于变量的每个值,仅 Select 包含列表中所有值的值.R

随机森林的带Shap值的蜂群图

根据纬度和距离连接两个数据集

R中Gamma回归模型均方误差的两种计算方法不一致

'使用`purrr::pwalk`从嵌套的嵌套框架中的列表列保存ggplots时出现未使用的参数错误

Geom_arcbar()中出错:找不到函数";geom_arcbar";

在R中的数据框上使用Apply()函数时,如何保留非数字列?

将列的值乘以在不同数据集中找到的值

多元正态分布的计算

如何在Quarto中使用美人鱼图表中的标记来加粗文本

需要一个函数来在第一行创建一个新变量,然后用新变量替换一个不同的变量(对于多行)

如何用不同长度的向量填充列表?