2014-03-29 46 views
4

我有data.table,我需要计算一些新值并选择具有min值的行。从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") 

# 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

# g_id item_no tdiff 
# 1: 2  27 12 

让行(该行实际上只有item_no)我可以使它在一个操作与tb?什么是最快速的方式来做到这一点(因为我需要做大约500,000行这个操作)?

+0

你是否在寻找:'TB [(GID),列表(ITEM_NO,TDIFF = {Z = ABS(time_no - TS) })] [,item_no [which.min(tdiff)],by = g_id]' –

+0

@GaryWeissman,谢谢!我发现我也可以写入选择结尾'[last(order(tdiff))] [[2]]' –

+0

很高兴帮助! data.tables非常适合这个东西。 –

回答

3

你可以尝试.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

的data.table电话可以链接在一起[][][]因此,所有你需要的是一个额外的指令抢最小值为每个g_id

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

相关问题