Aggrega un frame di dati basato su coppie di colonne non ordinate

Ho un set di dati che assomiglia a questo:

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 

Dove id1 e id2 sono nodes univoci in un grafico e la size è un valore assegnato al bordo diretto che li collega da id1 a id2 . Questo set di dati è abbastanza grande (poco più di 2 milioni di righe). Quello che mi piacerebbe fare è sumre la colonna delle dimensioni, raggruppata in coppie di nodes non ordinate di id1 e id2 . Ad esempio, nella prima riga, abbiamo id1=5400 e id2=5505 . Esiste un’altra riga nel frame di dati dove id1=5505 e id2=5400 . Nei dati raggruppati, la sum delle colonne delle dimensioni per queste due righe verrebbe aggiunta a una singola riga. Quindi, in altre parole, voglio riassumere i dati su cui sto raggruppando un insieme (non ordinato) di (id1, id2). Ho trovato un modo per farlo usando apply con una funzione personalizzata che controlla la coppia di colonne invertita nel set di dati completo, ma questo funziona atrocemente lento. Qualcuno sa di un modo per farlo in un altro modo, forse con plyr o con qualcosa nei pacchetti di base che sarebbe più efficiente?

Un modo è creare colonne aggiuntive con pmax e pmin di id1 e id2 come segue. data.table soluzione data.table qui.

 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 metodo 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 

Il mio metodo con la funzione 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