基于无序的列对聚合数据框

R_U*_*ser 7 aggregate r plyr

我有一个看起来像这样的数据集:

     id1  id2   size
1   5400 5505      7
2   5033 5458      1
3   5452 2873     24
4   5452 5213      2
5   5452 4242     26
6   4823 4823      4
7   5505 5400     11
Run Code Online (Sandbox Code Playgroud)

其中id1id2是在一个图形独特节点,并且size是分配给一个值涉及连接它们的边缘 id1 id2.这个数据集相当大(略多于200万行).我想这样做是和大小列,按分组无序节点对id1id2.例如,在第一行中,我们有id1=5400id2=5505.数据框中存在另一行,其中id1=5505id2=5400.在分组数据中,这两行的大小列的总和将添加到单个行中.换句话说,我想总结一下我在(无序)(id1,id2)集合上的数据.我已经找到了一种方法来使用apply自定义函数来检查完整数据集中的反向列对,但这种方法非常缓慢.有没有人知道以另一种方式做到这一点的方法,可能与plyr基础包中的某些内容相比更高效?

Aru*_*run 9

一种方法是与创建额外的列pmaxpminid1id2如下.我会data.table在这里使用解决方案.

require(data.table)
DT <- data.table(DF)
# Following mnel's suggestion, g1, g2 could be used directly in by
# and it could be even shortened by using `id1` and id2` as their names
DT.OUT <- DT[, list(size=sum(size)), 
        by=list(id1 = pmin(id1, id2), id2 = pmax(id1, id2))]
#     id1  id2 size
# 1: 5400 5505   18
# 2: 5033 5458    1
# 3: 5452 2873   24
# 4: 5452 5213    2
# 5: 5452 4242   26
# 6: 4823 4823    4
Run Code Online (Sandbox Code Playgroud)

  • 为什么不只是`DT [,list(size = sum(size)),by = list(id1 = pmin(id1,id2),id2 = pmax(id1,id2))]` - 负责重复,因为它不会创建它们. (4认同)

mar*_*ret 7

另一种方法:

R> library(igraph)
R> DF
   id1  id2 size
1 5400 5505    7
2 5033 5458    1
3 5452 2873   24
4 5452 5213    2
5 5452 4242   26
6 4823 4823    4
7 5505 5400   11
R> g  <- graph.data.frame(DF, directed=F)
R> g  <- simplify(g, edge.attr.comb="sum", remove.loops=FALSE)
R> DF <- get.data.frame(g)
R> DF
   id1  id2 size
1 5400 5505   18
2 5033 5458    1
3 5452 2873   24
4 5452 5213    2
5 5452 4242   26
6 4823 4823    4
Run Code Online (Sandbox Code Playgroud)