这是来自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;我得到以下图表:
这里DDD和EEE高于BBB,CCC。同样,JJJ将在III之前出现。如何更正此命令的函数treechart()始终正确?谢谢你的帮助。
答案 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
数据框中显示的顺序使用这些值。这将产生以下情节