R igraph包中树形图条目的顺序不正确

时间:2014-07-25 04:21:02

标签: r igraph

这是来自Creating treechart from tabbed text in R

的后续问题

我正在使用以下功能:

treechart = function(){
library(psych)
fields <- max(count.fields(textConnection(readClipboard()), sep = "\t"))
dat = read.table(text = readClipboard(), sep="\t",col.names = paste0("V", sequence(fields)), header=FALSE, fill=TRUE, strip.white=TRUE, stringsAsFactors=FALSE, na.strings="")

library(zoo)
library(igraph)
# To prepare the data
# carry forward the last value in columns if lower level (col to the right)
# is non-missing
dat[1] <- na.locf(dat[1], na.rm=FALSE)
for(i in ncol(dat):2)  {
  dat[[i-1]] <-  ifelse(!is.na(dat[[i]]), na.locf(dat[[i-1]], na.rm=F), dat[[i-1]])
}            

# get edges for graph
edges <- rbind(na.omit(dat[1:2]),
            do.call('rbind',
                    lapply(1:(ncol(dat)-2), function(i) 
                    na.omit(setNames(dat[(1+i):(2+i)],
                    names(dat[1:2])))))
                       )

# create graph
g <- graph.data.frame(edges)
# Plot graph
E(g)$curved <- 0
plot.igraph(g, vertex.size=0, edge.arrow.size=0 , layout=-layout.reingold.tilford(g)[,2:1])
}

我使用以下示例数据(由文本编辑器或电子表格中的标签分隔),我选择并使用control-C复制:

AAA 
    BBB
    CCC
    DDD
        III
        JJJ
            LLL
    EEE
        KKK
    FFF
    GGG

然后运行命令&#39; treechart()&#39;我得到以下图表: enter image description here

这里DDD和EEE高于BBB,CCC。同样,JJJ将在III之前出现。如何更正此命令的函数treechart()始终正确?谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

并不是说布局不正确,只是因为你要求layout.reingold.tilford布局以及你得到了什么。正如您所看到的,它喜欢将更复杂的分支移动到一侧。它不考虑顶点的指定顺序。我尝试编写一个新的布局函数来保存顺序

layout.tree.order <- function(g, vseq=V(g)$name, root=vseq[1]) {
    leaves <- vseq[sapply(V(g)[vseq], function(x) 
        length(unique(neighbors(g, x, mode="out"))))==0]
    ypos <- rep(NA, vcount(g))
    ypos[match(leaves, V(g)$name)]<-rev(seq(0,1,length.out=length(leaves)))

    calcypos<-function(g, vx) {
        if (!is.na(ypos[vx])) {
            p <- ypos[vx]
        } else {
            nb <- unique(neighbors(g, V(g)[vx]))
            p <- mean(sapply(nb, function(x) calcypos(g,x)))
        }
        ypos[vx] <<- p
        return(invisible(p))
    }
    calcypos(g, which(V(g)$name == root))
    xpos <- c(shortest.paths(g, V(g)[which(vseq == root)], V(g), mode="out"))

    cbind(xpos, ypos)
}

然后您只想更改treemap函数中的绘图线以添加一行并更改布局

vseq <- apply(dat, 1, function(x) na.omit(rev(x))[1])
plot.igraph(g, vertex.size=0, edge.arrow.size=0, 
    layout=layout.tree.order(g, vseq))

所以vseq这里是指定自上而下的排序。在这里,我们按照它们在dat数据框中显示的顺序使用这些值。这将产生以下情节

enter image description here