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

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

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

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

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

  1. for (i in 1:nrow(DT))
  2. DT[i,foo:=DT[n==DT[i]$n & abs(t-DT[i]$t)<=10,sum(v * abs(t-DT[i]$t) )]]
  3.  
  4. DT
  5. n t v foo
  6. 1: a 10 20 150
  7. 2: a 20 15 224
  8. 3: a 33 16 119
  9. 4: a 40 17 222
  10. 5: a 50 11 170
  11. 6: a 22 12 30
  12. 7: b 25 20 198
  13. 8: b 34 22 180
  14. 9: b 11 10 0

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

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

解决方法

尝试以下:
  1. 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的后缀

  1. merge(DT,by="n")

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

  1. # this will give you your desired rows
  2. [abs(t.x - t.y),]
  3.  
  4. # this is the expression you outlined
  5. [ ...,sum(v.x * abs(t.x - t.y)) ]
  6.  
  7. # summing by t.x and v.x
  8. [ ...,...,v.x)]) ]

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

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

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

  1. unique(merge(DT,sum(v.y * abs(t.x - t.y))),v.x)])

猜你在找的MsSQL相关文章