Agregue un dataframe basado en pares de columnas desordenadas

Tengo un conjunto de datos que se ve así:

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 

Donde id1 e id2 son nodos únicos en un gráfico, y el size es un valor asignado al borde dirigido que los conecta de id1 a id2 . Este conjunto de datos es bastante grande (poco más de 2 millones de filas). Lo que me gustaría hacer es sumr la columna de tamaño, agrupada por pares de nodos desordenados de id1 e id2 . Por ejemplo, en la primera fila, tenemos id1=5400 e id2=5505 . Existe otra fila en el dataframe donde id1=5505 e id2=5400 . En los datos agrupados, la sum de las columnas de tamaño para estas dos filas se agregaría a una sola fila. Entonces, en otras palabras, quiero resumir los datos en los que estoy agrupando en un conjunto (desordenado) de (id1, id2). He encontrado una forma de hacerlo usando apply con una función personalizada que comprueba el par de columnas invertidas en el conjunto completo de datos, pero esto funciona insoportablemente lento. ¿Alguien sabe de una manera de hacer esto de otra manera, quizás con plyr o con algo en los paquetes base que sería más eficiente?

Una forma es crear columnas adicionales con pmax y pmin de id1 e id2 siguiente manera. data.table solución data.table aquí.

 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 

un método alternativo:

 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 

Mi método con la función aggregate{stats} :

 > 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 > df[1:2] <- t(apply(df[1:2], 1, sort)) > aggregate(size ~ id1 + id2, data=df, FUN=sum) id1 id2 size 1 4823 4823 4 2 2873 5452 24 3 4242 5452 26 4 5213 5452 2 5 5033 5458 1 6 5400 5505 18