r – 如何在一个条件下自己加入一个data.table

前端之家收集整理的这篇文章主要介绍了r – 如何在一个条件下自己加入一个data.table前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想在我的data.table中添加一个新列.此列应包含满足特定条件的所有行的另一列的总和.一个例子:我的data.table如下所示:
require(data.table)
DT <- data.table(n=c("a","a","b","b"),t=c(10,20,33,40,50,22,25,34,11),v=c(20,15,16,17,11,12,10)
             )
DT
   n  t  v
1: a 10 20
2: a 20 15
3: a 33 16
4: a 40 17
5: a 50 11
6: a 22 12
7: b 25 20
8: b 34 22
9: b 11 10

对于每行x和每行i,其中abs(t [i] -t [x])= 10,我想计算

foo = sum( v[i] * abs(t[i] - t[x]) )

sql中,我将使用自联接来解决这个问题.在R中,我可以使用for循环:

for (i in 1:nrow(DT))
    DT[i,foo:=DT[n==DT[i]$n & abs(t-DT[i]$t)<=10,sum(v * abs(t-DT[i]$t) )]]

DT
   n  t  v foo
1: a 10 20 150
2: a 20 15 224
3: a 33 16 119
4: a 40 17 222
5: a 50 11 170
6: a 22 12  30
7: b 25 20 198
8: b 34 22 180
9: b 11 10   0

不幸的是,我必须经常这样做,我所用的表是相当大的.循环方法的工作原理太慢了.我玩sqldf包,没有真正的突破.我会喜欢使用一些data.table的魔法,我需要你的帮助:-).我认为需要的是某种自我加入,条件是t值的差异小于阈值.

跟进:
我有一个后续的问题:在我的申请中,这个加入是一遍又一遍地完成的. v的变化,但是t和n总是相同的.所以我正在考虑以某种方式存储哪些行属于一起.任何想法如何聪明地做到这一点?

解决方法

尝试以下:
unique(merge(DT,DT,by="n")[abs(t.x - t.y) <= 10,list(n,sum(v.x * abs(t.x - t.y))),by=list(t.x,v.x)])

上述细目:

您可以将表与自身合并,输出也将是一个data.table.请注意,列名称将被赋予.x和.y的后缀

merge(DT,by="n")

…您可以像任何DT一样过滤和计算

# this will give you your desired rows
[abs(t.x - t.y),]

# this is the expression you outlined
[ ...,sum(v.x * abs(t.x - t.y)) ]

# summing by t.x and v.x
[ ...,...,v.x)]) ]

然后最后将其全部包含在唯一的中以删除任何重复的行.

更新:这应该是一个评论,但太长

下面的行是什么匹配您的输出.这个和这个答案顶部的唯一区别是总和(v.y * …)中的术语v.y,但是by语句仍然使用v.x.是有意的吗?

unique(merge(DT,sum(v.y * abs(t.x - t.y))),v.x)])
原文链接:https://www.f2er.com/mssql/81313.html

猜你在找的MsSQL相关文章