Order of treechart entries not correct in R igraph package

こ雲淡風輕ζ 提交于 2019-12-04 06:44:08

问题


This is a follow-up question from : Creating treechart from tabbed text in R

I am using following function:

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

I am using following example data (separated by tabs in text editor or from spreadsheet) which I select and copy with control-C:

AAA 
    BBB
    CCC
    DDD
        III
        JJJ
            LLL
    EEE
        KKK
    FFF
    GGG

Then on running the command 'treechart()' I get following chart:

Here DDD and EEE are coming higher than BBB, CCC. Similarly, JJJ is coming before III. How can I correct the function treechart() for this order to be always correct? Thanks for your help.


回答1:


It's not that the layout is incorrect, it's just that you asked for the layout.reingold.tilford layout and that's what you got. As you can see, it likes to move more complex branches to one side. It does not consider the order that the vertices were specified. I tried writing a new layout function that would preserve order

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

Then you just want to change the plot line in your treemap function to add one additional line and change the layout

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

So the vseq here is what specifies the top-down ordering. Here we use the values in the order that they appear in your dat data frame. This will produce the following plot



来源:https://stackoverflow.com/questions/24948003/order-of-treechart-entries-not-correct-in-r-igraph-package

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!