加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

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

发布时间:2020-12-12 16:46:03 所属栏目:MsSql教程 来源:网络整理
导读:我想在我的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 v1:
我想在我的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)])

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读