将关系数据转换为R中的分层列表

时间:2016-03-29 01:06:00

标签: r hierarchical-data networkd3

这是我的第一个问题;所以,请温柔。

我有一些数据形式为:

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)是否有更好的方法为diagonalNetwork创建列表?

2)失败;如何修改我的循环以找出正确结构的列表?

3)我应该使用其他功能/包吗?

感谢您提供的任何帮助,我一直在对着这堵墙打我的头。关于更好地提出有关SO问题的方法的反馈也会受到欢迎。

澄清:

此处可以找到类似的问题Convert a data frame to a treeNetwork compatible list。但是它依赖于一个数据结构,其中根始终位于第一列中,并且其子项位于后续列中,而不是此问题中的边列表,这通常用于igraph中。

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

评论@Christoph Glur的答案 - 确保您的data.frame实际上是data.frame。我花了几个小时试图从一个单词创建一个树而无济于事,但as.data.frame(my.tibble)使它工作。

答案 2 :(得分:0)

感谢指出错误@Symbolix

受到@MrFlick评论的启发,建议从root开始并让孩子递归地创建列表元素:) ...肯定可以进一步改进以防止意外数据输入的健壮性

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选项