2016-03-29 94 views
6

這是我的第一個問題;所以,請溫柔。將關係數據轉換爲分級列表中的R

我有一些數據,在形式:

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 

本質上講,這是一種可以用來進行網絡地圖邊緣的列表:

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

enter image description here

我想將它轉換爲下面的diagonalNetwork函數中可以使用的表單。

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) 

像這樣:

enter image description here

當我嘗試使用這個循環來生成列表:

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) 

我得到這個錯誤:

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

1 )是th創建diagonalNetwork列表的更好方法是什麼?

2)失敗;我怎樣才能修改我的循環來打出正確結構的列表?

3)是否有我應該使用的整個其他函數/包?

感謝您給予的任何幫助,我一直在頭撞這堵牆。反饋更好的方式來提出關於SO的問題也會受到歡迎。

澄清:

類似的問題可以在這裏找到,Convert a data frame to a treeNetwork compatible list。然而,它依賴於一個數據結構,其中根始終在第一列,而其子節點在後續列中,而不是像這個問題中的邊界列表,這在igraph中是常用的。

+0

@Procrastinatus Maximus,我編輯它來澄清兩個問題之間的區別。那個人有着相同的最終目標,但沒有轉換關係數據,只有當根在第一列並且整個父 - 子結構在後續列中時才起作用,這在邊緣列表中不是這種情況。 –

+0

好吧,我已經重新打開了這個問題 – Jaap

回答

1

感謝您指出的@MrFlick評論啓發錯誤@Symbolix

,建議從根本入手,讓孩子遞歸創建列表元素:) ...當然可以進一步提高針對意外數據穩健性輸入

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])) 

順便說一句,如果我沒看錯的,也有在一個的igraph選擇layout.reingold.tilford

+0

這些返回不同的結構,在問題 – SymbolixAU

+0

@Symbolix發佈不錯的結構,結構是不同的,但只在排序。對於我的目標(圖),這不是一個問題。我將查看layout.reingold.tilford選項。 –

+0

通過允許我使用networkd3軟件包的一些功能,這對於我現在進行igraph繪製而不用重複工作的一些功能有很大幫助。謝謝。 –

9

你可以使用data.tree包,它做了很多轉換從和分層數據盒子外面:

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

評論@Christoph Glur的答案 - 確保data.frame實際上是一個data.frame。我剛剛花了幾個小時試圖從一個小竅門創建一棵樹無濟於事,但as.data.frame(my.tibble)使它工作。