【问题标题】:data.table operation chaining数据表操作链接
【发布时间】:2025-12-03 23:25:01
【问题描述】:

执行以下操作的最佳方式是什么:

假设我想找出 user_id 50 的 user_id。

我首先使用索引生成数据表,然后使用本质上是另一个 data.table 的内容进行过滤。有没有更有效的方法?

在本例中,我希望索引为 2,即 user_id 为 的行的索引

x<-data.table(user_id=c(1,-1,2,3),iqlevel=c(40,50,60,70))
x[,I:=.I,][user_id<0,I,]

【问题讨论】:

  • 可重现的示例帮助...

标签: r data.table


【解决方案1】:

我会有另一个答案:

x[user_id<0, which=TRUE]

并使用我的辅助工具运行一些计时:

library(data.table) # v1.9.5
# devtools::install_github("jangorecki/dtq")
# drat::addRepo("jangorecki"); install.packages("dtq")
library(dtq)

op <- data.table(user_id=c(1,-1,2,3),iqlevel=c(40,50,60,70))
sheffien <- copy(op)
jan <- copy(op)

r1 <- op[,I:=.I,][user_id<0,I,]
r2 <- sheffien[,.I[which(user_id<0)] ]
r3 <- jan[user_id<0, which=TRUE]

identical(r1,r2)
# [1] TRUE
identical(r2,r3)
# [1] TRUE

dtcalls <- dtl(print=TRUE) # collect logs
print(dtcalls)
#    seq dtq_id dtq_seq      src                           query           timestamp         env     elapsed in_rows out_rows
# 1:   1      1       1       op               [j = `:=`(I, .I)] 2015-08-07 14:01:10 R_GlobalEnv 0.001718847       4        4
# 2:   2      1       2       op        [i = user_id < 0, j = I] 2015-08-07 14:01:10 R_GlobalEnv 0.008719112       4       NA
# 3:   3      2       1 sheffien    [j = .I[which(user_id < 0)]] 2015-08-07 14:01:10 R_GlobalEnv 0.000662418       4       NA
# 4:   4      3       1      jan [i = user_id < 0, which = TRUE] 2015-08-07 14:01:10 R_GlobalEnv 0.000281067       4       NA

dtcalls[,.(query=paste(query, collapse=""), sec=sum(elapsed)),.(src)]
#         src                                     query         sec
# 1:       op [j = `:=`(I, .I)][i = user_id < 0, j = I] 0.010437959
# 2: sheffien              [j = .I[which(user_id < 0)]] 0.000662418
# 3:      jan           [i = user_id < 0, which = TRUE] 0.000281067

请记住,这只是在 4 行 data.table 上单次运行,因此请务必验证数据的速度。

【讨论】:

    【解决方案2】:

    给你:

    dt[,.I[which(user_id&lt;0)] ]

    【讨论】:

    • @Arun 不起作用,因为 .I 在后子集表上给出了结果...