2013-03-18 11 views
5

Mam zestaw danych, który wygląda mniej więcej tak:Agregat ramkę danych na podstawie nieuporządkowanych par kolumn

 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 

Gdzie id1 i id2 są unikalne węzły w wykresie, a size to wartość przypisana do skierowana krawędź łącząca je zid1naid2. Ten zbiór danych jest dość duży (nieco ponad 2 miliony wierszy). Chciałbym podsumować kolumnę rozmiaru pogrupowaną według nieuporządkowanych węzłów: z id1 i id2. Na przykład w pierwszym rzędzie mamy id1=5400 i id2=5505. Istnieje inny wiersz w ramce danych, gdzie id1=5505 i id2=5400. W zgrupowanych danych suma kolumn wielkości dla tych dwóch wierszy zostanie dodana do pojedynczego wiersza. Innymi słowy chcę podsumować dane, w których zgrupuję się na (niezamierzonym) zestawie (id1, id2). Znalazłem sposób, aby to zrobić przy użyciu apply z niestandardową funkcją, która sprawdza odwróconą parę kolumn w pełnym zestawie danych, ale działa to niesamowicie wolno. Czy ktoś wie o sposobie na zrobienie tego w inny sposób, być może z plyr lub z czymś w pakietach bazowych, które byłyby bardziej wydajne?

Odpowiedz

8

Jednym ze sposobów jest utworzenie dodatkowych kolumn z pmax i pmin z id1 i id2 w następujący sposób. Użyję tutaj rozwiązania 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 
+0

myślę pisząc go na kilku liniach zamiast kompozycje pomogłyby th OP + choć wpisać szybciej niż ja – statquant

+1

Można utworzyć G1 i G2 w argument. – mnel

+0

@mnel, to genialne. Dokona edycji. Każdy pomysł jak usunąć zduplikowane wiersze na podstawie 2 kolumn bez zmiennej temp? – Arun

3

alternatywna metoda:

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 
Powiązane problemy