9

これが私の最初の質問です。だから、優しくしてください。

次の形式のデータがあります。

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)

ここに画像の説明を入力

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)

このような:

ここに画像の説明を入力

このループを使用してリストを生成しようとすると:

    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) のリストを作成するより良い方法はありdiagonalNetworkますか?

2) それができない。ループを修正して、正しい構造のリストを追い出すにはどうすればよいですか?

3) 私が使用すべき他の関数/パッケージはありますか?

助けてくれてありがとう、私はしばらくこの壁に頭をぶつけていました。SO に関する質問をするためのより良い方法についてのフィードバックも歓迎します。

説明:

同様の質問がここにあります。Convert a data frame to a treeNetwork compatible list . ただし、ルートが常に最初の列にあり、その子が後続の列にあるデータ構造に依存しています。これは、igraph で一般的に使用されるこの質問のようなエッジのリストではありません。

4

2 に答える 2

11

箱から出して階層データとの間で多くの変換を行う 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)
于 2016-03-29T19:46:10.710 に答える
1

エラーを指摘してくれてありがとう@Symbolix

@MrFlick コメントに触発され、ルートから開始し、子にリスト要素を再帰的に作成させる提案:) ...予期しないデータ入力に対する堅牢性のために、さらに改善することができます

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 オプションもあります。

于 2016-03-29T02:31:05.413 に答える