2017-03-01 2 views
2

Ich habe eine 4 GB-Datei mit rund 2 Milliarden gerichteten Kanten im Format User1 FOLLOWS User 2, unten gezeigt.Schnell berechnen Anzahl der One-Way-, Zwei-Wege-Links von sehr großen Rand Liste

User1  User2 
7   37 
5   24 
7   8383932 
24   1 
3   8538 
37   7 

DF = structure(list(User1 = c(7L, 5L, 7L, 24L, 3L, 37L), User2 = c(37L, 
24L, 8383932L, 1L, 8538L, 7L)), .Names = c("User1", "User2"), row.names = c(NA, 
-6L), class = "data.frame") 

und so weiter. Ich möchte in der Lage sein, effizient die folgenden Ergebnisse

User  NumberFollowers  NumberFriends 
1   1      0 
7   1      1 
24   1      0 
37   1      1 
8383932  1      0 
8538  1      0 
5   0      0 
3   0      0 

und so weiter zu kommen, wo NumberFollowers ist die Zahl der „User1“ 's mit Links zu ihnen, und NumberFriends ist die Anzahl der Follower die sie haben, dass sie auch gemeinsam folgen.

Ich habe versucht derzeit

aggregate() 

jedoch unter Verwendung scheint es Fälle wie Benutzer 5 und Benutzer 3, die keine Freunde oder Follower haben zu ignorieren, aber sie selbst Menschen folgen.

Ich würde lieber nicht das ganze Ding durchlaufen müssen, da es ewig dauern wird mit wie vielen Kanten ich habe.

Gibt es einen guten, effizienten Weg, dies relativ schnell und schmerzlos zu tun?

Danke!

+0

Ich denke, Sie sollten verwenden, die für solche Dinge konzipiert ist. – Frank

+0

Ihr Ausgang sieht falsch aus. 37 hat einen Freund (7). – Frank

+0

Danke, das habe ich behoben. Kann iGraph mir eine Liste von Freunden/Followern zur Verfügung stellen, während ich die Unique-User ID behalte, so dass ich diese auf andere Datensätze, die ich habe, verweisen kann? – Jibril

Antwort

5

Hier ist eine Art und Weise:

library(data.table) 
setDT(DT) 

res0 <- rbind(
    DT[, .N, by=.(user=User2)][, lab := "followers"], 
    DT[.(User2, User1), on=names(DT), nomatch=0][, .N, by=.(user=User2)][, lab := "friends"] 
)[, dcast(.SD, user ~ lab, value.var = "N", fill = 0L)] 

     user followers friends 
1:  1   1  0 
2:  7   1  1 
3:  24   1  0 
4:  37   1  1 
5: 8538   1  0 
6: 8383932   1  0 

Dies schließt Benutzer ohne Anhänger, aber sie sind ziemlich einfach wieder hinzufügen, falls gewünscht.

DT selbst listet Anhänger; und DT[.(User2, User1), on=names(DT), nomatch=0] listet Freunde auf.

Dies ist nahe der Grenze dessen, was man mit diesen Daten im Tabellenformat vernünftig machen kann. Alles Züchter und Sie werden wirklich eine Grafik wollen. Siehe das igraph-Paket.


Sortierte Anmerkungen:

  • Die Syntax DT[i,j,by] bedeutet Teilmenge unter Verwendung von i; Gruppe von by; und tun j. Siehe ?data.table.
  • Aufgaben können wie DT[...][...] verkettet werden.
  • := ist ein spezielles Symbol für die Zuordnung zu einer Spalte.
  • .N ist eine spezielle Variable, die die Zeilen in einer Gruppe zählt. Siehe ?.N.
  • on= und nomatch= sind Helfer Argumente bei der Verwendung von i für eine "Join", auch in ?data.table.
  • dcast ist eine Hilfsfunktion für die Umformung vom Lang- zum Breitformat. Siehe ?dcast.
+1

Wow, das ist blitzschnell verglichen mit dem, was ich gemacht habe. Vielen Dank! Ich denke, ich werde nur die vollständige Liste der IDs mit der Liste der IDs mit Followern vergleichen, und wer nicht erscheint, anhängen mit Nullen. Danke nochmal. – Jibril

Verwandte Themen