2009-07-11 15 views
6

I eine data.frame mit 2 Spalten haben: Knoten A, Knoten B. Jeder Eintrag in dem Rahmen impliziert eine Kante in einem Graphen zwischen den Knoten A und B.einen Adjazenzliste von einem data.frame Erstellen

Es muss ein netter Einzeiler sein, um diesen data.frame in eine Adjazenzliste umzuwandeln. Irgendwelche Hinweise?

Antwort

6

quick and dirty ...

> edges <- data.frame(nodea=c(1,2,4,2,1), nodeb=c(1,2,3,4,5)) 

> adjlist <- by(edges, edges$nodea, function(x) x$nodeb) 

> for (i in as.character(unique(edges$nodea))) { 
+ cat(i, ' -> ', adjlist[[i]], '\n') 
+ } 

1 -> 1 5 
2 -> 2 4 
4 -> 3 

> adjlist 
edges$nodea: 1 
[1] 1 5 
------------------------------------------------------------ 
edges$nodea: 2 
[1] 2 4 
------------------------------------------------------------ 
edges$nodea: 4 
[1] 3 
+0

Guh. Ja. Das ist ein perfekter Liner. Seltsamerweise läuft meine for-Schleife-Lösung doppelt so schnell wie durch(). –

+0

in der Tat ist es nicht sehr schnell, wenn Ihre Tabelle 50.000 lang ist (mit ~ 5000 Bezeichnern). Gibt es schnellere Alternativen? –

0

Wie würden Sie sogar eine Adjazenzliste in R darstellen? es benötigt Listen variabler Größe für den Satz benachbarter Knoten; Dann musst du eine Liste verwenden(); aber was nützt es dann in R?

ich kann mir lahme Tricks mit sapply-ähnlichen Funktionen vorstellen, aber sie machen einen linearen Scan für jeden Knoten. Aber spielen Sie für 1 Minute, hier ist: eine Liste der Kindermädchen, wo der zweite Gegenstand jedes Paares die Adjazenzliste ist. Ausgabe ist verrückter als die Datastruktur wirklich ist.

> edgelist=data.frame(A=c(1,1,2,2,2),B=c(1,2,2,3,4)) 
> library(plyr) 
> llply(1:max(edgelist), function(a) list(node=a, adjacents=as.list(edgelist$B[edgelist$A==a]))) 
[[1]] 
[[1]]$node 
[1] 1 

[[1]]$adjacents 
[[1]]$adjacents[[1]] 
[1] 1 

[[1]]$adjacents[[2]] 
[1] 2 



[[2]] 
[[2]]$node 
[1] 2 

[[2]]$adjacents 
[[2]]$adjacents[[1]] 
[1] 2 

[[2]]$adjacents[[2]] 
[1] 3 

[[2]]$adjacents[[3]] 
[1] 4 



[[3]] 
[[3]]$node 
[1] 3 

[[3]]$adjacents 
list() 


[[4]] 
[[4]]$node 
[1] 4 

[[4]]$adjacents 
list() 
+0

Brendan - der Standard Weg (zumindest aus der Sicht von igraph) ist eine Liste von Scheitelpunkten - und jedes Listenelement ist ein Vektor benachbarter Scheitelpunkte. –

4
> edges <- data.frame(nodea=c(1,2,4,2,1), nodeb=c(1,2,3,4,5)) 

> attach(edges) 

> tapply(nodeb,nodea,unique) 

$`1` 
[1] 1 5 

$`2` 
[1] 2 4 

$`4` 
[1] 3 
+0

aus irgendeinem seltsamen Grund innerhalb von R 'tapply (as.character (node), as.character (nodea), unique)' ist 100s mal schneller bei der Umwandlung meiner sehr langen Tabelle (100.000 Zeilen) in eine Liste als 'tapply (nodeb, nodea, einmalig) '!!! –

11

Da Sie diesen markiert, wie etwa in der Funktionalität gebaut Verwendung?

Einziger Nachteil ist, dass die Scheitelpunkte null sind, was sich mit dem Wert von 0,6 ändern wird.

Verwandte Themen