2016-03-29 13 views
6

Dies ist meine erste Frage; Sei bitte sanft.Beziehungsdaten in hierarchische Liste umwandeln in R

Ich habe einige Daten, die in Form ist:

library('networkD3') 
    Relationships<- data.frame(Parent=c("earth","earth","forest","forest","ocean","ocean","ocean","ocean"), 
        Child=c("ocean","forest","tree","sasquatch","fish","seaweed","mantis shrimp","sea monster")) 
> Relationships 
    Parent   Child 
1 earth   ocean 
2 earth  forest 
3 forest   tree 
4 forest  sasquatch 
5 ocean   fish 
6 ocean  seaweed 
7 ocean mantis shrimp 
8 ocean sea monster 

Im Wesentlichen ist dies eine Liste von Kanten, die verwendet werden können, um eine Netzwerkkarte zu machen:

net <- graph_from_data_frame(d = Relationships, 
          directed = T) 
plot(net) 

enter image description here

Ich möchte es in ein Formular konvertieren, das in der diagonalNetwork Funktion unten verwendet werden konnte.

Hierarchical_list <- list(name = "earth", 
       children = list(list(name = "ocean", 
             children = list(list(name = "mantis shrimp"), 
                 list(name = "fish"), 
                 list(name = "sea monster"), 
                 list(name = "seaweed") 
                )), 
           list(name = "forest", 
             children = list(list(name = "sasquatch"), 
                 list(name = "tree") 
                )) 
       )) 
diagonalNetwork(Hierarchical_list) 

So:

enter image description here

Wenn ich versuche, um die Liste mit dieser Schleife zu generieren:

List_attempt <- list() 

levels<- levels(factor(Relationships$Parent)) 

for(n in 1:length(levels)){ 
    Children <- subset(Relationships, Relationships$Parent == levels[n], select = Child) 
    for(c in 1:length(Children)){ 
    sublist <- as.list(Children) 
    List_attempt <- list(List_attempt, name = levels[n],children = sublist) 
    } 
} 

diagonalNetwork(List_attempt) 

ich diesen Fehler:

Error in FUN(X[[i]], ...) : 
    'options' must be a fully named list, or have no names (NULL) 

1) Ist th Gibt es eine bessere Möglichkeit, eine Liste für diagonalNetwork zu erstellen?

2) Fehler; Wie kann ich meine Loops modifizieren, um eine Liste der korrekten Struktur zu erstellen?

3) Gibt es eine ganz andere Funktion/ein Paket, das ich verwenden sollte?

Danke für jede Hilfe, die Sie geben können, habe ich meinen Kopf für eine Weile gegen diese Wand geschlagen. Feedback zu besseren Möglichkeiten, Fragen zu SO zu stellen, wäre ebenfalls zu begrüßen.

Klarstellung:

Eine ähnliche Frage hier gefunden wird, Convert a data frame to a treeNetwork compatible list. Es beruht jedoch auf einer Datenstruktur, bei der sich der Stamm immer in der ersten Spalte und seine untergeordneten Elemente in nachfolgenden Spalten befinden, nicht eine Liste von Kanten wie in dieser Frage, die üblicherweise in igraph verwendet wird.

+0

@Procrastinatus Maximus, ich habe es bearbeitet, um den Unterschied zwischen den beiden Fragen zu klären. Dieser hat das gleiche Endziel, konvertiert jedoch keine Beziehungsdaten, er funktioniert nur, wenn der Stamm in der ersten Spalte steht und die gesamte Eltern-Kind-Struktur in den nachfolgenden Spalten ist, was in einer Liste von Kanten nicht der Fall ist. –

+0

ok, ich habe die Frage wieder geöffnet – Jaap

Antwort

1

Dank für den Hinweis auf den Fehler @Symbolix

von @MrFlick Kommentar inspiriert, einen Vorschlag von der Wurzel zu starten und Kind Listenelemente erstellen bekommen :) rekursiv ... sicherlich für Robustheit gegen unerwartete Daten weiter verbessert werden kann, btw Eingänge

library(igraph) 
library('networkD3') 
Relationships<- data.frame(Parent=c("earth","earth","forest","forest","ocean","ocean","ocean","ocean"), 
    Child=c("ocean","forest","tree","sasquatch","fish","seaweed","mantis shrimp","sea monster")) 
net <- graph_from_data_frame(d=Relationships, directed=T) 
plot(net) 

#net and Relationships as declared in question 
#get root 
root <- setdiff(Relationships$Parent, Relationships$Child) 

#traverse next layer and then recurve 
as.list.igraph <- function(thisNode) { 
    nm <- vertex_attr(net, "name", thisNode) 
    childNodes <- V(net)[which(shortest.paths(net, thisNode, mode="out") == 1)] 
    if (length(childNodes)==0) return(list(name=nm)) 
    list(name=nm, children=unname(lapply(childNodes, as.list.igraph))) 
} 

#plot D3 network 
diagonalNetwork(as.list.igraph(V(net)[root])) 

, wenn ich mich nicht irre, gibt es auch eine Option layout.reingold.tilford in IGRAPH

+0

Diese geben unterschiedliche Strukturen zu der in der Frage – SymbolixAU

+0

@Symbolix Guter Fang, die Strukturen sind anders, aber nur in der Bestellung. Für mein Ziel (die Grafik) ist das kein Problem. Ich werde in die Option layout.reingold.tilford schauen. –

+0

Dies wird mir sehr helfen, indem ich einige der Funktionen des Netzwerkd3-Pakets für einige der Dinge, die ich für die Erstellung von igraph-Plots mache, benutze, ohne doppelte Anstrengungen zu unternehmen. Vielen Dank. –

9

Sie könnten das data.tree Paket verwenden, die viele Konvertierungen von und zu hierarchischen Daten tut out of the box:

library('networkD3') 
Relationships<- data.frame(Parent=c("earth","earth","forest","forest","ocean","ocean","ocean","ocean"), 
          Child=c("ocean","forest","tree","sasquatch","fish","seaweed","mantis shrimp","sea monster")) 

library('data.tree') 
tree <- FromDataFrameNetwork(Relationships) 
tree 
lol <- ToListExplicit(tree, unname = TRUE) 
diagonalNetwork(lol) 
1

auf die Antwort von @ Christoph Glur Kommentierung - sicherzustellen, dass Ihre data.frame in der Tat ein data.frame. Ich habe nur ein paar Stunden damit verbracht, einen Baum aus einer Kleinigkeit ohne Erfolg zu erstellen, aber as.data.frame(my.tibble) hat es funktioniert.