从data.table中选择最小值的行

5

我有一个data.table,需要在其上计算一些新值,并选择具有min值的行。

tb <- data.table(g_id=c(1, 1, 1, 2, 2, 2, 3),
          item_no=c(24,25,26,27,28,29,30),
          time_no=c(100, 110, 120, 130, 140, 160, 160),
          key="g_id")

#    g_id item_no time_no
# 1:    1      24     100
# 2:    1      25     110
# 3:    1      26     120
# 4:    2      27     130
# 5:    2      28     140
# 6:    2      29     160
# 7:    3      30     160

ts  <- 118
gId <- 2

tb[.(gId), list(item_no, tdiff={z=abs(time_no - ts)})]

#    g_id item_no tdiff
# 1:    2      27    12
# 2:    2      28    22
# 3:    2      29    42

现在我需要获取具有最小 tdiff(实际上只需要获取该行的item_no)的行。

#    g_id item_no tdiff
# 1:    2      27    12

我能否使用 tb 在一次操作中完成此操作?这样做的最快方法是什么(因为我需要对大约500,000行执行此操作)?


你在寻找的是:tb[.(gId), list(item_no, tdiff={z=abs(time_no - ts)})][,item_no[which.min(tdiff)],by=g_id] - Gary Weissman
@GaryWeissman,谢谢!我发现我还可以写到选择的末尾 [last(order(tdiff))][[2]] - Katerina
很高兴能够帮助!data.table 对于处理这些东西非常的好。 - Gary Weissman
2个回答

4
你可以尝试使用.SD[][]来链接查询。
我理解的问题是首先更新一个新列,然后找到最小的tdiff。
library(data.table)
tb <- data.table(g_id=c(1, 1, 1, 2, 2, 2, 3),
             item_no=c(24,25,26,27,28,29,30),
             time_no=c(100, 110, 120, 130, 140, 160, 160),
             key="g_id")

ts <- 118

# My solution is quite simple
tb[, tdiff := list(tdiff=abs(time_no - ts))][, .SD[which.min(tdiff)], by = key(tb)]

我认为使用.SD更加合适。此外,你可以使用:=进行更新。
以下是输出结果:
   g_id item_no time_no tdiff
1:    1      26     120     2
2:    2      27     130    12
3:    3      30     160    42

1
数据表格调用可以链接起来使用[][][],因此您只需要一个额外的命令来获取每个g_id的最小值:

tb[.(gId), list(item_no, tdiff={z=abs(time_no - ts)})][,item_no[which.min(tdiff)],by=g_id]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接